mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
The deed (#2016)
This commit is contained in:
parent
7e3515e6eb
commit
b8d7cc3241
@ -290,14 +290,12 @@ pub enum Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<IoError> for Error {
|
impl From<IoError> for Error {
|
||||||
#[inline]
|
|
||||||
fn from(err: IoError) -> Error {
|
fn from(err: IoError) -> Error {
|
||||||
Error::IoError(err)
|
Error::IoError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SpirvError> for Error {
|
impl From<SpirvError> for Error {
|
||||||
#[inline]
|
|
||||||
fn from(err: SpirvError) -> Error {
|
fn from(err: SpirvError) -> Error {
|
||||||
Error::SpirvError(err)
|
Error::SpirvError(err)
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ pub struct VulkanoConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for VulkanoConfig {
|
impl Default for VulkanoConfig {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let device_extensions = DeviceExtensions {
|
let device_extensions = DeviceExtensions {
|
||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
@ -88,7 +89,7 @@ impl Default for VulkanoConfig {
|
|||||||
/// in the creation of [`VulkanoWindowRenderer`](crate::renderer::VulkanoWindowRenderer) through
|
/// in the creation of [`VulkanoWindowRenderer`](crate::renderer::VulkanoWindowRenderer) through
|
||||||
/// [`VulkanoWindows`](crate::window::VulkanoWindows).
|
/// [`VulkanoWindows`](crate::window::VulkanoWindows).
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano_util::context::{VulkanoConfig, VulkanoContext};
|
/// use vulkano_util::context::{VulkanoConfig, VulkanoContext};
|
||||||
@ -107,6 +108,7 @@ pub struct VulkanoContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for VulkanoContext {
|
impl Default for VulkanoContext {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
VulkanoContext::new(VulkanoConfig::default())
|
VulkanoContext::new(VulkanoConfig::default())
|
||||||
}
|
}
|
||||||
@ -245,16 +247,19 @@ impl VulkanoContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the name of the device.
|
/// Returns the name of the device.
|
||||||
|
#[inline]
|
||||||
pub fn device_name(&self) -> &str {
|
pub fn device_name(&self) -> &str {
|
||||||
&self.device.physical_device().properties().device_name
|
&self.device.physical_device().properties().device_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the type of the device.
|
/// Returns the type of the device.
|
||||||
|
#[inline]
|
||||||
pub fn device_type(&self) -> PhysicalDeviceType {
|
pub fn device_type(&self) -> PhysicalDeviceType {
|
||||||
self.device.physical_device().properties().device_type
|
self.device.physical_device().properties().device_type
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the maximum memory allocation of the device.
|
/// Returns the maximum memory allocation of the device.
|
||||||
|
#[inline]
|
||||||
pub fn max_memory(&self) -> u32 {
|
pub fn max_memory(&self) -> u32 {
|
||||||
self.device
|
self.device
|
||||||
.physical_device()
|
.physical_device()
|
||||||
@ -263,16 +268,19 @@ impl VulkanoContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the instance.
|
/// Returns the instance.
|
||||||
|
#[inline]
|
||||||
pub fn instance(&self) -> &Arc<Instance> {
|
pub fn instance(&self) -> &Arc<Instance> {
|
||||||
&self.instance
|
&self.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the device.
|
/// Returns the device.
|
||||||
|
#[inline]
|
||||||
pub fn device(&self) -> &Arc<Device> {
|
pub fn device(&self) -> &Arc<Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the graphics queue.
|
/// Returns the graphics queue.
|
||||||
|
#[inline]
|
||||||
pub fn graphics_queue(&self) -> &Arc<Queue> {
|
pub fn graphics_queue(&self) -> &Arc<Queue> {
|
||||||
&self.graphics_queue
|
&self.graphics_queue
|
||||||
}
|
}
|
||||||
@ -280,6 +288,7 @@ impl VulkanoContext {
|
|||||||
/// Returns the compute queue.
|
/// Returns the compute queue.
|
||||||
///
|
///
|
||||||
/// Depending on your device, this might be the same as graphics queue.
|
/// Depending on your device, this might be the same as graphics queue.
|
||||||
|
#[inline]
|
||||||
pub fn compute_queue(&self) -> &Arc<Queue> {
|
pub fn compute_queue(&self) -> &Arc<Queue> {
|
||||||
&self.compute_queue
|
&self.compute_queue
|
||||||
}
|
}
|
||||||
|
@ -33,11 +33,11 @@ pub type DeviceImageView = Arc<ImageView<StorageImage>>;
|
|||||||
/// Most common image format
|
/// Most common image format
|
||||||
pub const DEFAULT_IMAGE_FORMAT: Format = Format::R8G8B8A8_UNORM;
|
pub const DEFAULT_IMAGE_FORMAT: Format = Format::R8G8B8A8_UNORM;
|
||||||
|
|
||||||
/// A window renderer struct holding the winit window surface and functionality for organizing your render
|
/// A window renderer struct holding the winit window surface and functionality for organizing your
|
||||||
/// between frames.
|
/// render between frames.
|
||||||
///
|
///
|
||||||
/// Begin rendering with [`VulkanoWindowRenderer::acquire`] and finish with [`VulkanoWindowRenderer::present`].
|
/// Begin rendering with [`VulkanoWindowRenderer::acquire`] and finish with
|
||||||
/// Between those, you should execute your command buffers.
|
/// [`VulkanoWindowRenderer::present`]. Between those, you should execute your command buffers.
|
||||||
///
|
///
|
||||||
/// The intended usage of this struct is through [`crate::window::VulkanoWindows`].
|
/// The intended usage of this struct is through [`crate::window::VulkanoWindows`].
|
||||||
pub struct VulkanoWindowRenderer {
|
pub struct VulkanoWindowRenderer {
|
||||||
@ -56,8 +56,9 @@ pub struct VulkanoWindowRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanoWindowRenderer {
|
impl VulkanoWindowRenderer {
|
||||||
/// Creates a new [`VulkanoWindowRenderer`] which is used to orchestrate your rendering with Vulkano.
|
/// Creates a new [`VulkanoWindowRenderer`] which is used to orchestrate your rendering with
|
||||||
/// Pass [`WindowDescriptor`] and optionally a function modifying the [`SwapchainCreateInfo`](vulkano::swapchain::SwapchainCreateInfo) parameters.
|
/// Vulkano. Pass [`WindowDescriptor`] and optionally a function modifying the
|
||||||
|
/// [`SwapchainCreateInfo`](vulkano::swapchain::SwapchainCreateInfo) parameters.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vulkano_context: &VulkanoContext,
|
vulkano_context: &VulkanoContext,
|
||||||
window: winit::window::Window,
|
window: winit::window::Window,
|
||||||
@ -142,6 +143,7 @@ impl VulkanoWindowRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set window renderer present mode. This triggers a swapchain recreation.
|
/// Set window renderer present mode. This triggers a swapchain recreation.
|
||||||
|
#[inline]
|
||||||
pub fn set_present_mode(&mut self, present_mode: vulkano::swapchain::PresentMode) {
|
pub fn set_present_mode(&mut self, present_mode: vulkano::swapchain::PresentMode) {
|
||||||
if self.present_mode != present_mode {
|
if self.present_mode != present_mode {
|
||||||
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 {
|
pub fn swapchain_format(&self) -> Format {
|
||||||
self.final_views[self.image_index as usize]
|
self.final_views[self.image_index as usize]
|
||||||
.format()
|
.format()
|
||||||
.unwrap()
|
.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 {
|
pub fn image_index(&self) -> u32 {
|
||||||
self.image_index
|
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> {
|
pub fn graphics_queue(&self) -> Arc<Queue> {
|
||||||
self.graphics_queue.clone()
|
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> {
|
pub fn compute_queue(&self) -> Arc<Queue> {
|
||||||
self.compute_queue.clone()
|
self.compute_queue.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render target surface
|
/// Render target surface.
|
||||||
|
#[inline]
|
||||||
pub fn surface(&self) -> Arc<Surface<Window>> {
|
pub fn surface(&self) -> Arc<Surface<Window>> {
|
||||||
self.surface.clone()
|
self.surface.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Winit window (you can manipulate window through this).
|
/// Winit window (you can manipulate window through this).
|
||||||
|
#[inline]
|
||||||
pub fn window(&self) -> &Window {
|
pub fn window(&self) -> &Window {
|
||||||
self.surface.window()
|
self.surface.window()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Size of the physical window
|
/// Size of the physical window.
|
||||||
|
#[inline]
|
||||||
pub fn window_size(&self) -> [f32; 2] {
|
pub fn window_size(&self) -> [f32; 2] {
|
||||||
let size = self.window().inner_size();
|
let size = self.window().inner_size();
|
||||||
[size.width as f32, size.height as f32]
|
[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] {
|
pub fn swapchain_image_size(&self) -> [u32; 2] {
|
||||||
self.final_views[0].image().dimensions().width_height()
|
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 {
|
pub fn swapchain_image_view(&self) -> SwapchainImageView {
|
||||||
self.final_views[self.image_index as usize].clone()
|
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] {
|
pub fn resolution(&self) -> [f32; 2] {
|
||||||
let size = self.window().inner_size();
|
let size = self.window().inner_size();
|
||||||
let scale_factor = self.window().scale_factor();
|
let scale_factor = self.window().scale_factor();
|
||||||
@ -207,17 +219,21 @@ impl VulkanoWindowRenderer {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn aspect_ratio(&self) -> f32 {
|
pub fn aspect_ratio(&self) -> f32 {
|
||||||
let dims = self.window_size();
|
let dims = self.window_size();
|
||||||
dims[0] / dims[1]
|
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) {
|
pub fn resize(&mut self) {
|
||||||
self.recreate_swapchain = true;
|
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) {
|
pub fn add_additional_image_view(&mut self, key: usize, format: Format, usage: ImageUsage) {
|
||||||
let size = self.swapchain_image_size();
|
let size = self.swapchain_image_size();
|
||||||
let image = StorageImage::general_purpose_image_view(
|
let image = StorageImage::general_purpose_image_view(
|
||||||
@ -230,20 +246,24 @@ impl VulkanoWindowRenderer {
|
|||||||
self.additional_image_views.insert(key, image);
|
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 {
|
pub fn get_additional_image_view(&mut self, key: usize) -> DeviceImageView {
|
||||||
self.additional_image_views.get(&key).unwrap().clone()
|
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) {
|
pub fn remove_additional_image_view(&mut self, key: usize) {
|
||||||
self.additional_image_views.remove(&key);
|
self.additional_image_views.remove(&key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Begin your rendering by calling `acquire`.
|
/// Begin your rendering by calling `acquire`.
|
||||||
/// Returns a [`GpuFuture`](vulkano::sync::GpuFuture) representing the time after which the swapchain image has been acquired
|
/// Returns a [`GpuFuture`](vulkano::sync::GpuFuture) representing the time after which the
|
||||||
/// and previous frame ended.
|
/// swapchain image has been acquired and previous frame ended.
|
||||||
/// Execute your command buffers after calling this function and finish rendering by calling [`VulkanoWindowRenderer::present`].
|
/// 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> {
|
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)
|
// Recreate swap chain if needed (when resizing of window occurs or swapchain is outdated)
|
||||||
// Also resize render views if needed
|
// Also resize render views if needed
|
||||||
@ -272,10 +292,13 @@ impl VulkanoWindowRenderer {
|
|||||||
Ok(future.boxed())
|
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
|
/// Depending on your implementation, you may want to wait on your future. For example, a
|
||||||
/// dispatch using an image that's being later drawn should probably be waited on.
|
/// 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) {
|
pub fn present(&mut self, after_future: Box<dyn GpuFuture>, wait_future: bool) {
|
||||||
let future = after_future
|
let future = after_future
|
||||||
.then_swapchain_present(
|
.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) {
|
fn recreate_swapchain_and_views(&mut self) {
|
||||||
let dimensions: [u32; 2] = self.window().inner_size().into();
|
let dimensions: [u32; 2] = self.window().inner_size().into();
|
||||||
let (new_swapchain, new_images) = match self.swapchain.recreate(SwapchainCreateInfo {
|
let (new_swapchain, new_images) = match self.swapchain.recreate(SwapchainCreateInfo {
|
||||||
|
@ -20,22 +20,25 @@ use winit::{
|
|||||||
window::{CursorGrabMode, WindowId},
|
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 vulkano_util::context::{VulkanoConfig, VulkanoContext};
|
||||||
/// use winit::event_loop::EventLoop;
|
/// use winit::event_loop::EventLoop;
|
||||||
/// use vulkano_util::window::VulkanoWindows;
|
/// use vulkano_util::window::VulkanoWindows;
|
||||||
///
|
///
|
||||||
/// #[test]
|
/// #[test]
|
||||||
/// fn test() {
|
/// fn test() {
|
||||||
/// let context = VulkanoContext::new(VulkanoConfig::default());
|
/// let context = VulkanoContext::new(VulkanoConfig::default());
|
||||||
/// let event_loop = EventLoop::new();
|
/// let event_loop = EventLoop::new();
|
||||||
/// let mut vulkano_windows = VulkanoWindows::default();
|
/// let mut vulkano_windows = VulkanoWindows::default();
|
||||||
/// let _id1 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
|
/// let _id1 = vulkano_windows.create_window(&event_loop, &context, &Default::default(), |_| {});
|
||||||
/// let _id2 = 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
|
///
|
||||||
|
/// // You should now have two windows.
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -45,8 +48,8 @@ pub struct VulkanoWindows {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VulkanoWindows {
|
impl VulkanoWindows {
|
||||||
/// Creates a winit window with [`VulkanoWindowRenderer`] based on the given [`WindowDescriptor`]
|
/// Creates a winit window with [`VulkanoWindowRenderer`] based on the given
|
||||||
/// input and swapchain creation modifications
|
/// [`WindowDescriptor`] input and swapchain creation modifications.
|
||||||
pub fn create_window(
|
pub fn create_window(
|
||||||
&mut self,
|
&mut self,
|
||||||
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
|
event_loop: &winit::event_loop::EventLoopWindowTarget<()>,
|
||||||
@ -171,7 +174,8 @@ impl VulkanoWindows {
|
|||||||
id
|
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> {
|
pub fn get_primary_renderer_mut(&mut self) -> Option<&mut VulkanoWindowRenderer> {
|
||||||
if self.primary.is_some() {
|
if self.primary.is_some() {
|
||||||
self.get_renderer_mut(self.primary.unwrap())
|
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> {
|
pub fn get_primary_renderer(&self) -> Option<&VulkanoWindowRenderer> {
|
||||||
if self.primary.is_some() {
|
if self.primary.is_some() {
|
||||||
self.get_renderer(self.primary.unwrap())
|
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> {
|
pub fn get_primary_window(&self) -> Option<&winit::window::Window> {
|
||||||
if self.primary.is_some() {
|
if self.primary.is_some() {
|
||||||
self.get_window(self.primary.unwrap())
|
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(
|
pub fn get_renderer_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
id: winit::window::WindowId,
|
id: winit::window::WindowId,
|
||||||
@ -206,22 +213,26 @@ impl VulkanoWindows {
|
|||||||
self.windows.get_mut(&id)
|
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> {
|
pub fn get_renderer(&self, id: winit::window::WindowId) -> Option<&VulkanoWindowRenderer> {
|
||||||
self.windows.get(&id)
|
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> {
|
pub fn get_window(&self, id: winit::window::WindowId) -> Option<&winit::window::Window> {
|
||||||
self.windows.get(&id).map(|v_window| v_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> {
|
pub fn primary_window_id(&self) -> Option<winit::window::WindowId> {
|
||||||
self.primary
|
self.primary
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove renderer by window id
|
/// Remove renderer by window id.
|
||||||
|
#[inline]
|
||||||
pub fn remove_renderer(&mut self, id: winit::window::WindowId) {
|
pub fn remove_renderer(&mut self, id: winit::window::WindowId) {
|
||||||
self.windows.remove(&id);
|
self.windows.remove(&id);
|
||||||
if let Some(primary) = self.primary {
|
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> {
|
pub fn iter(&self) -> Iter<'_, WindowId, VulkanoWindowRenderer> {
|
||||||
self.windows.iter()
|
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> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, WindowId, VulkanoWindowRenderer> {
|
||||||
self.windows.iter_mut()
|
self.windows.iter_mut()
|
||||||
}
|
}
|
||||||
@ -301,7 +314,8 @@ pub enum WindowMode {
|
|||||||
BorderlessFullscreen,
|
BorderlessFullscreen,
|
||||||
/// Creates a fullscreen window that will render at desktop resolution.
|
/// 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,
|
SizedFullscreen,
|
||||||
/// Creates a fullscreen window that uses the maximum supported size.
|
/// Creates a fullscreen window that uses the maximum supported size.
|
||||||
Fullscreen,
|
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)`.
|
/// If there are some scaling problems on X11 try to set this option to `Some(1.0)`.
|
||||||
pub scale_factor_override: Option<f64>,
|
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,
|
pub title: String,
|
||||||
/// The window's [`PresentMode`].
|
/// The window's [`PresentMode`].
|
||||||
///
|
///
|
||||||
@ -349,6 +364,7 @@ pub struct WindowDescriptor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WindowDescriptor {
|
impl Default for WindowDescriptor {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
WindowDescriptor {
|
WindowDescriptor {
|
||||||
title: "Vulkano App".to_string(),
|
title: "Vulkano App".to_string(),
|
||||||
@ -384,6 +400,7 @@ pub struct WindowResizeConstraints {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for WindowResizeConstraints {
|
impl Default for WindowResizeConstraints {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
min_width: 180.,
|
min_width: 180.,
|
||||||
|
@ -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
|
/// 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.
|
/// from being dropped before the surface.
|
||||||
#[inline]
|
|
||||||
pub fn create_surface_from_winit<W>(
|
pub fn create_surface_from_winit<W>(
|
||||||
window: W,
|
window: W,
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
@ -56,13 +55,13 @@ pub trait VkSurfaceBuild<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<E> VkSurfaceBuild<E> for WindowBuilder {
|
impl<E> VkSurfaceBuild<E> for WindowBuilder {
|
||||||
#[inline]
|
|
||||||
fn build_vk_surface(
|
fn build_vk_surface(
|
||||||
self,
|
self,
|
||||||
event_loop: &EventLoopWindowTarget<E>,
|
event_loop: &EventLoopWindowTarget<E>,
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
) -> Result<Arc<Surface<Window>>, CreationError> {
|
) -> Result<Arc<Surface<Window>>, CreationError> {
|
||||||
let window = self.build(event_loop)?;
|
let window = self.build(event_loop)?;
|
||||||
|
|
||||||
Ok(create_surface_from_winit(window, instance)?)
|
Ok(create_surface_from_winit(window, instance)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,22 +76,20 @@ pub enum CreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for CreationError {
|
impl Error for CreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
CreationError::SurfaceCreationError(ref err) => Some(err),
|
CreationError::SurfaceCreationError(err) => Some(err),
|
||||||
CreationError::WindowCreationError(ref err) => Some(err),
|
CreationError::WindowCreationError(err) => Some(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CreationError {
|
impl Display for CreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
CreationError::SurfaceCreationError(_) => "error while creating the surface",
|
CreationError::SurfaceCreationError(_) => "error while creating the surface",
|
||||||
CreationError::WindowCreationError(_) => "error while creating the window",
|
CreationError::WindowCreationError(_) => "error while creating the window",
|
||||||
}
|
}
|
||||||
@ -101,21 +98,18 @@ impl Display for CreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<SurfaceCreationError> for CreationError {
|
impl From<SurfaceCreationError> for CreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SurfaceCreationError) -> CreationError {
|
fn from(err: SurfaceCreationError) -> CreationError {
|
||||||
CreationError::SurfaceCreationError(err)
|
CreationError::SurfaceCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WindowCreationError> for CreationError {
|
impl From<WindowCreationError> for CreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: WindowCreationError) -> CreationError {
|
fn from(err: WindowCreationError) -> CreationError {
|
||||||
CreationError::WindowCreationError(err)
|
CreationError::WindowCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
#[inline]
|
|
||||||
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
win: W,
|
win: W,
|
||||||
@ -243,7 +237,6 @@ unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
#[inline]
|
|
||||||
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
unsafe fn winit_to_surface<W: SafeBorrow<Window>>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
win: W,
|
win: W,
|
||||||
|
@ -287,20 +287,20 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
|
|||||||
/// Note that the `robust_buffer_access` is guaranteed to be supported by all Vulkan
|
/// Note that the `robust_buffer_access` is guaranteed to be supported by all Vulkan
|
||||||
/// implementations.
|
/// implementations.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use vulkano::device::Features;
|
/// use vulkano::device::Features;
|
||||||
/// # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
/// # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
||||||
/// let minimal_features = Features {
|
/// let minimal_features = Features {
|
||||||
/// geometry_shader: true,
|
/// geometry_shader: true,
|
||||||
/// .. Features::empty()
|
/// ..Features::empty()
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// let optimal_features = vulkano::device::Features {
|
/// let optimal_features = vulkano::device::Features {
|
||||||
/// geometry_shader: true,
|
/// geometry_shader: true,
|
||||||
/// tessellation_shader: true,
|
/// tessellation_shader: true,
|
||||||
/// .. Features::empty()
|
/// ..Features::empty()
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// if !physical_device.supported_features().is_superset_of(&minimal_features) {
|
/// 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));
|
/// assert!(optimal_features.is_superset_of(&minimal_features));
|
||||||
/// let features_to_request = optimal_features.intersection(physical_device.supported_features());
|
/// let features_to_request = optimal_features.intersection(physical_device.supported_features());
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Features {
|
pub struct Features {
|
||||||
#(#struct_items)*
|
#(#struct_items)*
|
||||||
@ -325,7 +324,8 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Features {
|
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(
|
pub(super) fn check_requirements(
|
||||||
&self,
|
&self,
|
||||||
supported: &Features,
|
supported: &Features,
|
||||||
|
@ -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.
|
/// Note: for 16-bit floating point values, you need to import the [`half::f16`] type.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # #[macro_use] extern crate vulkano;
|
/// # #[macro_use] extern crate vulkano;
|
||||||
|
@ -384,7 +384,7 @@ fn bit_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> TokenStream {
|
|||||||
);
|
);
|
||||||
|
|
||||||
quote! {
|
quote! {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct #name {
|
pub struct #name {
|
||||||
#(#members_items)*
|
#(#members_items)*
|
||||||
@ -524,7 +524,8 @@ fn value_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> TokenStream {
|
|||||||
|
|
||||||
let derives = match name_string.as_str() {
|
let derives = match name_string.as_str() {
|
||||||
"ExecutionModel" => quote! { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] },
|
"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! {
|
quote! {
|
||||||
|
@ -110,7 +110,6 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn uninitialized(
|
pub unsafe fn uninitialized(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
@ -173,7 +172,6 @@ where
|
|||||||
///
|
///
|
||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
/// - Panics if `len` is zero.
|
/// - Panics if `len` is zero.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn uninitialized_array(
|
pub unsafe fn uninitialized_array(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
len: DeviceSize,
|
len: DeviceSize,
|
||||||
@ -274,7 +272,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
/// Returns the queue families this buffer can be used on.
|
/// Returns the queue families this buffer can be used on.
|
||||||
#[inline]
|
|
||||||
pub fn queue_family_indices(&self) -> &[u32] {
|
pub fn queue_family_indices(&self) -> &[u32] {
|
||||||
&self.queue_family_indices
|
&self.queue_family_indices
|
||||||
}
|
}
|
||||||
@ -294,7 +291,6 @@ where
|
|||||||
/// After this function successfully locks the buffer, any attempt to submit a command buffer
|
/// 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
|
/// that uses it in exclusive mode will fail. You can still submit this buffer for non-exclusive
|
||||||
/// accesses (ie. reads).
|
/// accesses (ie. reads).
|
||||||
#[inline]
|
|
||||||
pub fn read(&self) -> Result<ReadLock<'_, T, A>, ReadLockError> {
|
pub fn read(&self) -> Result<ReadLock<'_, T, A>, ReadLockError> {
|
||||||
let mut state = self.inner.state();
|
let mut state = self.inner.state();
|
||||||
let buffer_range = self.inner().offset..self.inner().offset + self.size();
|
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
|
/// 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.
|
/// that uses it and any attempt to call `read()` will return an error.
|
||||||
#[inline]
|
|
||||||
pub fn write(&self) -> Result<WriteLock<'_, T, A>, WriteLockError> {
|
pub fn write(&self) -> Result<WriteLock<'_, T, A>, WriteLockError> {
|
||||||
let mut state = self.inner.state();
|
let mut state = self.inner.state();
|
||||||
let buffer_range = self.inner().offset..self.inner().offset + self.size();
|
let buffer_range = self.inner().offset..self.inner().offset + self.size();
|
||||||
@ -370,7 +365,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> BufferInner<'_> {
|
fn inner(&self) -> BufferInner<'_> {
|
||||||
BufferInner {
|
BufferInner {
|
||||||
buffer: &self.inner,
|
buffer: &self.inner,
|
||||||
@ -378,7 +372,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size(&self) -> DeviceSize {
|
fn size(&self) -> DeviceSize {
|
||||||
self.inner.size()
|
self.inner.size()
|
||||||
}
|
}
|
||||||
@ -389,7 +382,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync + 'static,
|
A: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
@ -407,7 +399,6 @@ unsafe impl<T, A> DeviceOwned for CpuAccessibleBuffer<T, A>
|
|||||||
where
|
where
|
||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.device()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
@ -418,7 +409,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner() && self.size() == other.size()
|
self.inner() == other.inner() && self.size() == other.size()
|
||||||
}
|
}
|
||||||
@ -436,7 +426,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
self.size().hash(state);
|
self.size().hash(state);
|
||||||
@ -463,7 +452,6 @@ where
|
|||||||
T: BufferContents + ?Sized + 'a,
|
T: BufferContents + ?Sized + 'a,
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut state = self.inner.inner.state();
|
let mut state = self.inner.inner.state();
|
||||||
@ -479,7 +467,6 @@ where
|
|||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
self.data
|
self.data
|
||||||
}
|
}
|
||||||
@ -506,7 +493,6 @@ where
|
|||||||
T: BufferContents + ?Sized + 'a,
|
T: BufferContents + ?Sized + 'a,
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner
|
self.inner
|
||||||
@ -529,7 +515,6 @@ where
|
|||||||
{
|
{
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn deref(&self) -> &T {
|
fn deref(&self) -> &T {
|
||||||
self.data
|
self.data
|
||||||
}
|
}
|
||||||
@ -540,7 +525,6 @@ where
|
|||||||
T: BufferContents + ?Sized + 'a,
|
T: BufferContents + ?Sized + 'a,
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn deref_mut(&mut self) -> &mut T {
|
fn deref_mut(&mut self) -> &mut T {
|
||||||
self.data
|
self.data
|
||||||
}
|
}
|
||||||
@ -558,7 +542,6 @@ pub enum ReadLockError {
|
|||||||
impl Error for ReadLockError {}
|
impl Error for ReadLockError {}
|
||||||
|
|
||||||
impl Display for ReadLockError {
|
impl Display for ReadLockError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
@ -587,7 +570,6 @@ pub enum WriteLockError {
|
|||||||
impl Error for WriteLockError {}
|
impl Error for WriteLockError {}
|
||||||
|
|
||||||
impl Display for WriteLockError {
|
impl Display for WriteLockError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
|
@ -59,17 +59,19 @@ use std::{
|
|||||||
///
|
///
|
||||||
/// # Usage
|
/// # Usage
|
||||||
///
|
///
|
||||||
/// Since a `DeviceLocalBuffer` can only be directly accessed by the GPU, data cannot be transfered between
|
/// Since a `DeviceLocalBuffer` can only be directly accessed by the GPU, data cannot be transfered
|
||||||
/// the host process and the buffer alone. One must use additional buffers which are accessible to the CPU as
|
/// between the host process and the buffer alone. One must use additional buffers which are
|
||||||
/// staging areas, then use command buffers to execute the necessary data transfers.
|
/// 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,
|
/// Despite this, if one knows in advance that a buffer will not need to be frequently accessed by
|
||||||
/// then there may be significant performance gains by using a `DeviceLocalBuffer` over a buffer type which
|
/// the host, then there may be significant performance gains by using a `DeviceLocalBuffer` over a
|
||||||
/// allows host access.
|
/// 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};
|
/// use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer};
|
||||||
@ -111,21 +113,20 @@ use std::{
|
|||||||
/// )
|
/// )
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
/// cbb.copy_buffer(CopyBufferInfo::buffers(
|
/// cbb.copy_buffer(CopyBufferInfo::buffers(
|
||||||
/// temporary_accessible_buffer,
|
/// temporary_accessible_buffer,
|
||||||
/// device_local_buffer.clone(),
|
/// device_local_buffer.clone(),
|
||||||
/// ))
|
/// ))
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
/// let cb = cbb.build().unwrap();
|
/// let cb = cbb.build().unwrap();
|
||||||
///
|
///
|
||||||
/// // Execute copy command and wait for completion before proceeding.
|
/// // Execute copy command and wait for completion before proceeding.
|
||||||
/// cb.execute(queue.clone())
|
/// cb.execute(queue.clone())
|
||||||
/// .unwrap()
|
/// .unwrap()
|
||||||
/// .then_signal_fence_and_flush()
|
/// .then_signal_fence_and_flush()
|
||||||
/// .unwrap()
|
/// .unwrap()
|
||||||
/// .wait(None /* timeout */)
|
/// .wait(None /* timeout */)
|
||||||
/// .unwrap()
|
/// .unwrap()
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeviceLocalBuffer<T, A = PotentialDedicatedAllocation<StandardMemoryPoolAlloc>>
|
pub struct DeviceLocalBuffer<T, A = PotentialDedicatedAllocation<StandardMemoryPoolAlloc>>
|
||||||
where
|
where
|
||||||
@ -153,7 +154,6 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
@ -180,9 +180,9 @@ where
|
|||||||
/// Builds a `DeviceLocalBuffer` that copies its data from another buffer.
|
/// Builds a `DeviceLocalBuffer` that copies its data from another buffer.
|
||||||
///
|
///
|
||||||
/// This function returns two objects: the newly-created buffer, and a future representing
|
/// 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
|
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you
|
||||||
/// either submit your operation after this future, or execute this future and wait for it to
|
/// must either submit your operation after this future, or execute this future and wait for it
|
||||||
/// be finished before submitting your own operation.
|
/// to be finished before submitting your own operation.
|
||||||
pub fn from_buffer<B>(
|
pub fn from_buffer<B>(
|
||||||
source: Arc<B>,
|
source: Arc<B>,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
@ -242,9 +242,9 @@ where
|
|||||||
/// submits the command buffer as a future.
|
/// submits the command buffer as a future.
|
||||||
///
|
///
|
||||||
/// This function returns two objects: the newly-created buffer, and a future representing
|
/// 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
|
/// the initial upload operation. In order to be allowed to use the `DeviceLocalBuffer`, you
|
||||||
/// either submit your operation after this future, or execute this future and wait for it to
|
/// must either submit your operation after this future, or execute this future and wait for it
|
||||||
/// be finished before submitting your own operation.
|
/// to be finished before submitting your own operation.
|
||||||
///
|
///
|
||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
@ -316,7 +316,6 @@ where
|
|||||||
///
|
///
|
||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
/// - Panics if `len` is zero.
|
/// - Panics if `len` is zero.
|
||||||
#[inline]
|
|
||||||
pub fn array(
|
pub fn array(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
len: DeviceSize,
|
len: DeviceSize,
|
||||||
@ -453,6 +452,7 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
let mem_reqs = buffer.memory_requirements();
|
let mem_reqs = buffer.memory_requirements();
|
||||||
|
|
||||||
Ok((buffer, mem_reqs))
|
Ok((buffer, mem_reqs))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -471,7 +471,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
/// Returns the queue families this buffer can be used on.
|
/// Returns the queue families this buffer can be used on.
|
||||||
#[inline]
|
|
||||||
pub fn queue_family_indices(&self) -> &[u32] {
|
pub fn queue_family_indices(&self) -> &[u32] {
|
||||||
&self.queue_family_indices
|
&self.queue_family_indices
|
||||||
}
|
}
|
||||||
@ -481,7 +480,6 @@ unsafe impl<T, A> DeviceOwned for DeviceLocalBuffer<T, A>
|
|||||||
where
|
where
|
||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.device()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
@ -492,7 +490,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> BufferInner<'_> {
|
fn inner(&self) -> BufferInner<'_> {
|
||||||
BufferInner {
|
BufferInner {
|
||||||
buffer: &self.inner,
|
buffer: &self.inner,
|
||||||
@ -500,7 +497,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size(&self) -> DeviceSize {
|
fn size(&self) -> DeviceSize {
|
||||||
self.inner.size()
|
self.inner.size()
|
||||||
}
|
}
|
||||||
@ -511,7 +507,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync + 'static,
|
A: Send + Sync + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
@ -530,7 +525,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner() && self.size() == other.size()
|
self.inner() == other.inner() && self.size() == other.size()
|
||||||
}
|
}
|
||||||
@ -548,7 +542,6 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
A: Send + Sync,
|
A: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
self.size().hash(state);
|
self.size().hash(state);
|
||||||
@ -562,7 +555,6 @@ pub enum DeviceLocalBufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for DeviceLocalBufferCreationError {
|
impl Error for DeviceLocalBufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::DeviceMemoryAllocationError(err) => Some(err),
|
Self::DeviceMemoryAllocationError(err) => Some(err),
|
||||||
@ -572,7 +564,6 @@ impl Error for DeviceLocalBufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DeviceLocalBufferCreationError {
|
impl Display for DeviceLocalBufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::DeviceMemoryAllocationError(err) => err.fmt(f),
|
Self::DeviceMemoryAllocationError(err) => err.fmt(f),
|
||||||
@ -582,14 +573,12 @@ impl Display for DeviceLocalBufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<DeviceMemoryError> for DeviceLocalBufferCreationError {
|
impl From<DeviceMemoryError> for DeviceLocalBufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(e: DeviceMemoryError) -> Self {
|
fn from(e: DeviceMemoryError) -> Self {
|
||||||
Self::DeviceMemoryAllocationError(e)
|
Self::DeviceMemoryAllocationError(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CommandBufferBeginError> for DeviceLocalBufferCreationError {
|
impl From<CommandBufferBeginError> for DeviceLocalBufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(e: CommandBufferBeginError) -> Self {
|
fn from(e: CommandBufferBeginError) -> Self {
|
||||||
Self::CommandBufferBeginError(e)
|
Self::CommandBufferBeginError(e)
|
||||||
}
|
}
|
||||||
|
@ -125,22 +125,18 @@ unsafe impl<T> BufferContents for T
|
|||||||
where
|
where
|
||||||
T: Pod + Send + Sync,
|
T: Pod + Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn as_bytes(&self) -> &[u8] {
|
fn as_bytes(&self) -> &[u8] {
|
||||||
bytes_of(self)
|
bytes_of(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<&T, PodCastError> {
|
fn from_bytes(bytes: &[u8]) -> Result<&T, PodCastError> {
|
||||||
try_from_bytes(bytes)
|
try_from_bytes(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut T, PodCastError> {
|
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut T, PodCastError> {
|
||||||
try_from_bytes_mut(bytes)
|
try_from_bytes_mut(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_of_element() -> DeviceSize {
|
fn size_of_element() -> DeviceSize {
|
||||||
1
|
1
|
||||||
}
|
}
|
||||||
@ -150,22 +146,18 @@ unsafe impl<T> BufferContents for [T]
|
|||||||
where
|
where
|
||||||
T: Pod + Send + Sync,
|
T: Pod + Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn as_bytes(&self) -> &[u8] {
|
fn as_bytes(&self) -> &[u8] {
|
||||||
cast_slice(self)
|
cast_slice(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_bytes(bytes: &[u8]) -> Result<&[T], PodCastError> {
|
fn from_bytes(bytes: &[u8]) -> Result<&[T], PodCastError> {
|
||||||
try_cast_slice(bytes)
|
try_cast_slice(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut [T], PodCastError> {
|
fn from_bytes_mut(bytes: &mut [u8]) -> Result<&mut [T], PodCastError> {
|
||||||
try_cast_slice_mut(bytes)
|
try_cast_slice_mut(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size_of_element() -> DeviceSize {
|
fn size_of_element() -> DeviceSize {
|
||||||
size_of::<T>() as DeviceSize
|
size_of::<T>() as DeviceSize
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ use std::{
|
|||||||
///
|
///
|
||||||
/// This object doesn't correspond to any Vulkan object. It exists for API convenience.
|
/// This object doesn't correspond to any Vulkan object. It exists for API convenience.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// Creating a slice:
|
/// Creating a slice:
|
||||||
///
|
///
|
||||||
@ -41,7 +41,7 @@ use std::{
|
|||||||
/// # let buffer: std::sync::Arc<vulkano::buffer::DeviceLocalBuffer<[u8]>> = return;
|
/// # let buffer: std::sync::Arc<vulkano::buffer::DeviceLocalBuffer<[u8]>> = return;
|
||||||
/// let _slice = BufferSlice::from(&buffer).slice(12 .. 14).unwrap();
|
/// let _slice = BufferSlice::from(&buffer).slice(12 .. 14).unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
///
|
#[derive(Debug)]
|
||||||
pub struct BufferSlice<T: ?Sized, B> {
|
pub struct BufferSlice<T: ?Sized, B> {
|
||||||
marker: PhantomData<T>,
|
marker: PhantomData<T>,
|
||||||
resource: Arc<B>,
|
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.
|
// We need to implement `Clone` manually, otherwise the derive adds a `T: Clone` requirement.
|
||||||
impl<T: ?Sized, B> Clone for BufferSlice<T, B> {
|
impl<T: ?Sized, B> Clone for BufferSlice<T, B> {
|
||||||
#[inline]
|
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
BufferSlice {
|
BufferSlice {
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
@ -63,7 +62,6 @@ impl<T: ?Sized, B> Clone for BufferSlice<T, B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized, B> BufferSlice<T, B> {
|
impl<T: ?Sized, B> BufferSlice<T, B> {
|
||||||
#[inline]
|
|
||||||
pub fn from_typed_buffer_access(r: Arc<B>) -> Arc<BufferSlice<T, B>>
|
pub fn from_typed_buffer_access(r: Arc<B>) -> Arc<BufferSlice<T, B>>
|
||||||
where
|
where
|
||||||
B: TypedBufferAccess<Content = T>,
|
B: TypedBufferAccess<Content = T>,
|
||||||
@ -84,13 +82,11 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the offset of that slice within the buffer.
|
/// Returns the offset of that slice within the buffer.
|
||||||
#[inline]
|
|
||||||
pub fn offset(&self) -> DeviceSize {
|
pub fn offset(&self) -> DeviceSize {
|
||||||
self.offset
|
self.offset
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size of that slice in bytes.
|
/// Returns the size of that slice in bytes.
|
||||||
#[inline]
|
|
||||||
pub fn size(&self) -> DeviceSize {
|
pub fn size(&self) -> DeviceSize {
|
||||||
self.size
|
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
|
/// This method builds an object that represents a slice of the buffer. No actual operation
|
||||||
/// is performed.
|
/// is performed.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// TODO
|
/// 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**
|
/// You **must** return a reference to an element from the parameter. The closure **must not**
|
||||||
/// panic.
|
/// panic.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn slice_custom<F, R: ?Sized>(&self, f: F) -> Arc<BufferSlice<R, B>>
|
pub unsafe fn slice_custom<F, R: ?Sized>(&self, f: F) -> Arc<BufferSlice<R, B>>
|
||||||
where
|
where
|
||||||
F: for<'r> FnOnce(&'r T) -> &'r R, // TODO: bounds on R
|
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
|
/// 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.
|
/// of a region that contains a single type of data.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use std::sync::Arc;
|
/// # 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.
|
/// Correct `offset` and `size` must be ensured before using this `BufferSlice` on the device.
|
||||||
/// See `BufferSlice::slice` for adjusting these properties.
|
/// See `BufferSlice::slice` for adjusting these properties.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn reinterpret<R: ?Sized>(&self) -> Arc<BufferSlice<R, B>> {
|
pub unsafe fn reinterpret<R: ?Sized>(&self) -> Arc<BufferSlice<R, B>> {
|
||||||
Arc::new(BufferSlice {
|
Arc::new(BufferSlice {
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
@ -166,7 +160,6 @@ impl<T: ?Sized, B> BufferSlice<T, B> {
|
|||||||
|
|
||||||
impl<T, B> BufferSlice<[T], B> {
|
impl<T, B> BufferSlice<[T], B> {
|
||||||
/// Returns the number of elements in this slice.
|
/// Returns the number of elements in this slice.
|
||||||
#[inline]
|
|
||||||
pub fn len(&self) -> DeviceSize {
|
pub fn len(&self) -> DeviceSize {
|
||||||
debug_assert_eq!(self.size() % size_of::<T>() as DeviceSize, 0);
|
debug_assert_eq!(self.size() % size_of::<T>() as DeviceSize, 0);
|
||||||
self.size() / size_of::<T>() as DeviceSize
|
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.
|
/// Reduces the slice to just one element of the array.
|
||||||
///
|
///
|
||||||
/// Returns `None` if out of range.
|
/// Returns `None` if out of range.
|
||||||
#[inline]
|
|
||||||
pub fn index(&self, index: DeviceSize) -> Option<Arc<BufferSlice<T, B>>> {
|
pub fn index(&self, index: DeviceSize) -> Option<Arc<BufferSlice<T, B>>> {
|
||||||
if index >= self.len() {
|
if index >= self.len() {
|
||||||
return None;
|
return None;
|
||||||
@ -192,7 +184,6 @@ impl<T, B> BufferSlice<[T], B> {
|
|||||||
/// Reduces the slice to just a range of the array.
|
/// Reduces the slice to just a range of the array.
|
||||||
///
|
///
|
||||||
/// Returns `None` if out of range.
|
/// Returns `None` if out of range.
|
||||||
#[inline]
|
|
||||||
pub fn slice(&self, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], B>>> {
|
pub fn slice(&self, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], B>>> {
|
||||||
if range.end > self.len() {
|
if range.end > self.len() {
|
||||||
return None;
|
return None;
|
||||||
@ -212,7 +203,6 @@ where
|
|||||||
B: BufferAccess,
|
B: BufferAccess,
|
||||||
T: Send + Sync + ?Sized,
|
T: Send + Sync + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> BufferInner<'_> {
|
fn inner(&self) -> BufferInner<'_> {
|
||||||
let inner = self.resource.inner();
|
let inner = self.resource.inner();
|
||||||
BufferInner {
|
BufferInner {
|
||||||
@ -221,7 +211,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size(&self) -> DeviceSize {
|
fn size(&self) -> DeviceSize {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
@ -232,7 +221,6 @@ where
|
|||||||
B: BufferAccess + 'static,
|
B: BufferAccess + 'static,
|
||||||
T: Send + Sync + ?Sized + 'static,
|
T: Send + Sync + ?Sized + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
@ -250,14 +238,12 @@ unsafe impl<T: ?Sized, B> DeviceOwned for BufferSlice<T, B>
|
|||||||
where
|
where
|
||||||
B: DeviceOwned,
|
B: DeviceOwned,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.resource.device()
|
self.resource.device()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, B> From<BufferSlice<T, B>> for BufferSlice<[T], B> {
|
impl<T, B> From<BufferSlice<T, B>> for BufferSlice<[T], B> {
|
||||||
#[inline]
|
|
||||||
fn from(r: BufferSlice<T, B>) -> BufferSlice<[T], B> {
|
fn from(r: BufferSlice<T, B>) -> BufferSlice<[T], B> {
|
||||||
BufferSlice {
|
BufferSlice {
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
@ -273,7 +259,6 @@ where
|
|||||||
T: Send + Sync,
|
T: Send + Sync,
|
||||||
B: BufferAccess,
|
B: BufferAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner() && self.size() == other.size()
|
self.inner() == other.inner() && self.size() == other.size()
|
||||||
}
|
}
|
||||||
@ -291,7 +276,6 @@ where
|
|||||||
T: Send + Sync,
|
T: Send + Sync,
|
||||||
B: BufferAccess,
|
B: BufferAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
self.size().hash(state);
|
self.size().hash(state);
|
||||||
|
@ -279,6 +279,7 @@ impl UnsafeBuffer {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::Buffer,
|
handle: ash::vk::Buffer,
|
||||||
@ -307,7 +308,6 @@ impl UnsafeBuffer {
|
|||||||
|
|
||||||
/// Returns the memory requirements for this buffer.
|
/// Returns the memory requirements for this buffer.
|
||||||
pub fn memory_requirements(&self) -> MemoryRequirements {
|
pub fn memory_requirements(&self) -> MemoryRequirements {
|
||||||
#[inline]
|
|
||||||
fn align(val: DeviceSize, al: DeviceSize) -> DeviceSize {
|
fn align(val: DeviceSize, al: DeviceSize) -> DeviceSize {
|
||||||
al * (1 + (val - 1) / al)
|
al * (1 + (val - 1) / al)
|
||||||
}
|
}
|
||||||
@ -443,6 +443,7 @@ impl UnsafeBuffer {
|
|||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,7 +512,6 @@ impl PartialEq for UnsafeBuffer {
|
|||||||
impl Eq for UnsafeBuffer {}
|
impl Eq for UnsafeBuffer {}
|
||||||
|
|
||||||
impl Hash for UnsafeBuffer {
|
impl Hash for UnsafeBuffer {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device.hash(state);
|
self.device.hash(state);
|
||||||
@ -590,17 +590,15 @@ pub enum BufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for BufferCreationError {
|
impl Error for BufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
BufferCreationError::AllocError(ref err) => Some(err),
|
BufferCreationError::AllocError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for BufferCreationError {
|
impl Display for BufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::AllocError(_) => write!(f, "allocating memory failed"),
|
Self::AllocError(_) => write!(f, "allocating memory failed"),
|
||||||
@ -614,24 +612,24 @@ impl Display for BufferCreationError {
|
|||||||
),
|
),
|
||||||
Self::MaxBufferSizeExceeded { .. } => write!(
|
Self::MaxBufferSizeExceeded { .. } => write!(
|
||||||
f,
|
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 {
|
impl From<OomError> for BufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> BufferCreationError {
|
fn from(err: OomError) -> BufferCreationError {
|
||||||
BufferCreationError::AllocError(err.into())
|
BufferCreationError::AllocError(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for BufferCreationError {
|
impl From<VulkanError> for BufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> BufferCreationError {
|
fn from(err: VulkanError) -> BufferCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -646,7 +644,6 @@ impl From<VulkanError> for BufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for BufferCreationError {
|
impl From<RequirementNotMet> for BufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -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
|
/// This method can be used when you want to perform an operation on some part of the buffer
|
||||||
/// and not on the whole buffer.
|
/// and not on the whole buffer.
|
||||||
#[inline]
|
|
||||||
fn slice<T>(self: &Arc<Self>, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], Self>>>
|
fn slice<T>(self: &Arc<Self>, range: Range<DeviceSize>) -> Option<Arc<BufferSlice<[T], Self>>>
|
||||||
where
|
where
|
||||||
Self: Sized + TypedBufferAccess<Content = [T]>,
|
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
|
/// 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.
|
/// buffer and not on the whole buffer.
|
||||||
#[inline]
|
|
||||||
fn index<T>(self: &Arc<Self>, index: DeviceSize) -> Option<Arc<BufferSlice<T, Self>>>
|
fn index<T>(self: &Arc<Self>, index: DeviceSize) -> Option<Arc<BufferSlice<T, Self>>>
|
||||||
where
|
where
|
||||||
Self: Sized + TypedBufferAccess<Content = [T]>,
|
Self: Sized + TypedBufferAccess<Content = [T]>,
|
||||||
@ -121,6 +119,7 @@ pub trait BufferAccessObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl BufferAccessObject for Arc<dyn BufferAccess> {
|
impl BufferAccessObject for Arc<dyn BufferAccess> {
|
||||||
|
#[inline]
|
||||||
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
fn as_buffer_access_object(&self) -> Arc<dyn BufferAccess> {
|
||||||
self.clone()
|
self.clone()
|
||||||
}
|
}
|
||||||
@ -141,12 +140,10 @@ where
|
|||||||
T: SafeDeref + Send + Sync,
|
T: SafeDeref + Send + Sync,
|
||||||
T::Target: BufferAccess,
|
T::Target: BufferAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> BufferInner<'_> {
|
fn inner(&self) -> BufferInner<'_> {
|
||||||
(**self).inner()
|
(**self).inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn size(&self) -> DeviceSize {
|
fn size(&self) -> DeviceSize {
|
||||||
(**self).size()
|
(**self).size()
|
||||||
}
|
}
|
||||||
@ -192,7 +189,6 @@ impl PartialEq for dyn BufferAccess {
|
|||||||
impl Eq for dyn BufferAccess {}
|
impl Eq for dyn BufferAccess {}
|
||||||
|
|
||||||
impl Hash for dyn BufferAccess {
|
impl Hash for dyn BufferAccess {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
self.size().hash(state);
|
self.size().hash(state);
|
||||||
@ -213,7 +209,6 @@ pub enum BufferDeviceAddressError {
|
|||||||
impl Error for BufferDeviceAddressError {}
|
impl Error for BufferDeviceAddressError {}
|
||||||
|
|
||||||
impl Display for BufferDeviceAddressError {
|
impl Display for BufferDeviceAddressError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -224,7 +219,6 @@ impl Display for BufferDeviceAddressError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::BufferMissingUsage => write!(
|
Self::BufferMissingUsage => write!(
|
||||||
f,
|
f,
|
||||||
"the device address usage flag was not set on this buffer",
|
"the device address usage flag was not set on this buffer",
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
//! In order to create a view from a buffer, the buffer must have been created with either the
|
//! 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.
|
//! `uniform_texel_buffer` or the `storage_texel_buffer` usage.
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use std::sync::Arc;
|
//! # use std::sync::Arc;
|
||||||
@ -235,7 +235,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the buffer associated to this view.
|
/// Returns the buffer associated to this view.
|
||||||
#[inline]
|
|
||||||
pub fn buffer(&self) -> &Arc<B> {
|
pub fn buffer(&self) -> &Arc<B> {
|
||||||
&self.buffer
|
&self.buffer
|
||||||
}
|
}
|
||||||
@ -245,7 +244,6 @@ impl<B> Drop for BufferView<B>
|
|||||||
where
|
where
|
||||||
B: BufferAccess + ?Sized,
|
B: BufferAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fns = self.buffer.inner().buffer.device().fns();
|
let fns = self.buffer.inner().buffer.device().fns();
|
||||||
@ -264,7 +262,6 @@ where
|
|||||||
{
|
{
|
||||||
type Object = ash::vk::BufferView;
|
type Object = ash::vk::BufferView;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn internal_object(&self) -> ash::vk::BufferView {
|
fn internal_object(&self) -> ash::vk::BufferView {
|
||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
@ -274,7 +271,6 @@ unsafe impl<B> DeviceOwned for BufferView<B>
|
|||||||
where
|
where
|
||||||
B: BufferAccess + ?Sized,
|
B: BufferAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.buffer.device()
|
self.buffer.device()
|
||||||
}
|
}
|
||||||
@ -284,7 +280,6 @@ impl<B> PartialEq for BufferView<B>
|
|||||||
where
|
where
|
||||||
B: BufferAccess + ?Sized,
|
B: BufferAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.device() == other.device()
|
self.handle == other.handle && self.device() == other.device()
|
||||||
}
|
}
|
||||||
@ -296,7 +291,6 @@ impl<B> Hash for BufferView<B>
|
|||||||
where
|
where
|
||||||
B: BufferAccess + ?Sized,
|
B: BufferAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -359,24 +353,18 @@ pub enum BufferViewCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for BufferViewCreationError {
|
impl Error for BufferViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
BufferViewCreationError::OomError(ref err) => Some(err),
|
BufferViewCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for BufferViewCreationError {
|
impl Display for BufferViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(
|
Self::OomError(_) => write!(f, "out of memory when creating buffer view"),
|
||||||
f,
|
|
||||||
"out of memory when creating buffer view",
|
|
||||||
),
|
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -385,10 +373,10 @@ impl Display for BufferViewCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::BufferMissingUsage => write!(
|
Self::BufferMissingUsage => write!(
|
||||||
f,
|
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!(
|
Self::OffsetNotAligned { .. } => write!(
|
||||||
f,
|
f,
|
||||||
@ -398,34 +386,29 @@ impl Display for BufferViewCreationError {
|
|||||||
f,
|
f,
|
||||||
"the range within the buffer is not a multiple of the required alignment",
|
"the range within the buffer is not a multiple of the required alignment",
|
||||||
),
|
),
|
||||||
Self::UnsupportedFormat => write!(
|
Self::UnsupportedFormat => {
|
||||||
f,
|
write!(f, "the requested format is not supported for this usage")
|
||||||
"the requested format is not supported for this usage",
|
}
|
||||||
),
|
Self::MaxTexelBufferElementsExceeded => {
|
||||||
Self::MaxTexelBufferElementsExceeded => write!(
|
write!(f, "the `max_texel_buffer_elements` limit has been exceeded")
|
||||||
f,
|
}
|
||||||
"the `max_texel_buffer_elements` limit has been exceeded",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for BufferViewCreationError {
|
impl From<OomError> for BufferViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for BufferViewCreationError {
|
impl From<VulkanError> for BufferViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
OomError::from(err).into()
|
OomError::from(err).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for BufferViewCreationError {
|
impl From<RequirementNotMet> for BufferViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -455,22 +438,18 @@ where
|
|||||||
B: BufferAccess + ?Sized + 'static,
|
B: BufferAccess + ?Sized + 'static,
|
||||||
Arc<B>: BufferAccessObject,
|
Arc<B>: BufferAccessObject,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn buffer(&self) -> Arc<dyn BufferAccess> {
|
fn buffer(&self) -> Arc<dyn BufferAccess> {
|
||||||
self.buffer.as_buffer_access_object()
|
self.buffer.as_buffer_access_object()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn format(&self) -> Option<Format> {
|
fn format(&self) -> Option<Format> {
|
||||||
self.format
|
self.format
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn format_features(&self) -> &FormatFeatures {
|
fn format_features(&self) -> &FormatFeatures {
|
||||||
&self.format_features
|
&self.format_features
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn range(&self) -> Range<DeviceSize> {
|
fn range(&self) -> Range<DeviceSize> {
|
||||||
self.range.clone()
|
self.range.clone()
|
||||||
}
|
}
|
||||||
@ -486,7 +465,6 @@ impl PartialEq for dyn BufferViewAbstract {
|
|||||||
impl Eq for dyn BufferViewAbstract {}
|
impl Eq for dyn BufferViewAbstract {}
|
||||||
|
|
||||||
impl Hash for dyn BufferViewAbstract {
|
impl Hash for dyn BufferViewAbstract {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.internal_object().hash(state);
|
self.internal_object().hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
|
@ -83,14 +83,12 @@ pub(super) enum RenderPassStateType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<BeginRenderPassState> for RenderPassStateType {
|
impl From<BeginRenderPassState> for RenderPassStateType {
|
||||||
#[inline]
|
|
||||||
fn from(val: BeginRenderPassState) -> Self {
|
fn from(val: BeginRenderPassState) -> Self {
|
||||||
Self::BeginRenderPass(val)
|
Self::BeginRenderPass(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<BeginRenderingState> for RenderPassStateType {
|
impl From<BeginRenderingState> for RenderPassStateType {
|
||||||
#[inline]
|
|
||||||
fn from(val: BeginRenderingState) -> Self {
|
fn from(val: BeginRenderingState) -> Self {
|
||||||
Self::BeginRendering(val)
|
Self::BeginRendering(val)
|
||||||
}
|
}
|
||||||
@ -532,21 +530,18 @@ pub enum CommandBufferBeginError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for CommandBufferBeginError {
|
impl Error for CommandBufferBeginError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CommandBufferBeginError {
|
impl Display for CommandBufferBeginError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -555,7 +550,6 @@ impl Display for CommandBufferBeginError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::ColorAttachmentFormatUsageNotSupported { attachment_index } => write!(
|
Self::ColorAttachmentFormatUsageNotSupported { attachment_index } => write!(
|
||||||
f,
|
f,
|
||||||
"color attachment {} has a format that does not support that usage",
|
"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",
|
"the depth and stencil attachments have different formats",
|
||||||
),
|
),
|
||||||
Self::FramebufferNotCompatible => {
|
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 { .. } => {
|
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!(
|
Self::StencilAttachmentFormatUsageNotSupported => write!(
|
||||||
f,
|
f,
|
||||||
@ -584,14 +578,12 @@ impl Display for CommandBufferBeginError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for CommandBufferBeginError {
|
impl From<OomError> for CommandBufferBeginError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for CommandBufferBeginError {
|
impl From<RequirementNotMet> for CommandBufferBeginError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -605,7 +597,6 @@ where
|
|||||||
P: CommandPoolBuilderAlloc,
|
P: CommandPoolBuilderAlloc,
|
||||||
{
|
{
|
||||||
/// Builds the command buffer.
|
/// Builds the command buffer.
|
||||||
#[inline]
|
|
||||||
pub fn build(self) -> Result<PrimaryAutoCommandBuffer<P::Alloc>, BuildError> {
|
pub fn build(self) -> Result<PrimaryAutoCommandBuffer<P::Alloc>, BuildError> {
|
||||||
if self.render_pass_state.is_some() {
|
if self.render_pass_state.is_some() {
|
||||||
return Err(BuildError::RenderPassActive);
|
return Err(BuildError::RenderPassActive);
|
||||||
@ -638,7 +629,6 @@ where
|
|||||||
P: CommandPoolBuilderAlloc,
|
P: CommandPoolBuilderAlloc,
|
||||||
{
|
{
|
||||||
/// Builds the command buffer.
|
/// Builds the command buffer.
|
||||||
#[inline]
|
|
||||||
pub fn build(self) -> Result<SecondaryAutoCommandBuffer<P::Alloc>, BuildError> {
|
pub fn build(self) -> Result<SecondaryAutoCommandBuffer<P::Alloc>, BuildError> {
|
||||||
if !self.query_state.is_empty() {
|
if !self.query_state.is_empty() {
|
||||||
return Err(BuildError::QueryActive);
|
return Err(BuildError::QueryActive);
|
||||||
@ -676,7 +666,6 @@ pub enum BuildError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for BuildError {
|
impl Error for BuildError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
@ -698,27 +687,23 @@ impl Display for BuildError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for BuildError {
|
impl From<OomError> for BuildError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||||
#[inline]
|
|
||||||
pub(super) fn queue_family_properties(&self) -> &QueueFamilyProperties {
|
pub(super) fn queue_family_properties(&self) -> &QueueFamilyProperties {
|
||||||
&self.device().physical_device().queue_family_properties()[self.queue_family_index as usize]
|
&self.device().physical_device().queue_family_properties()[self.queue_family_index as usize]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the binding/setting state.
|
/// Returns the binding/setting state.
|
||||||
#[inline]
|
|
||||||
pub fn state(&self) -> CommandBufferState<'_> {
|
pub fn state(&self) -> CommandBufferState<'_> {
|
||||||
self.inner.state()
|
self.inner.state()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<L, P> DeviceOwned for AutoCommandBufferBuilder<L, P> {
|
unsafe impl<L, P> DeviceOwned for AutoCommandBufferBuilder<L, P> {
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.device()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
@ -733,7 +718,6 @@ pub struct PrimaryAutoCommandBuffer<P = StandardCommandPoolAlloc> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<P> DeviceOwned for PrimaryAutoCommandBuffer<P> {
|
unsafe impl<P> DeviceOwned for PrimaryAutoCommandBuffer<P> {
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.device()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
@ -743,12 +727,10 @@ unsafe impl<P> PrimaryCommandBuffer for PrimaryAutoCommandBuffer<P>
|
|||||||
where
|
where
|
||||||
P: CommandPoolAlloc,
|
P: CommandPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeCommandBuffer {
|
fn inner(&self) -> &UnsafeCommandBuffer {
|
||||||
self.inner.as_ref()
|
self.inner.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn lock_submit(
|
fn lock_submit(
|
||||||
&self,
|
&self,
|
||||||
future: &dyn GpuFuture,
|
future: &dyn GpuFuture,
|
||||||
@ -793,7 +775,6 @@ where
|
|||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn unlock(&self) {
|
unsafe fn unlock(&self) {
|
||||||
// Because of panic safety, we unlock the inner command buffer first.
|
// Because of panic safety, we unlock the inner command buffer first.
|
||||||
self.inner.unlock();
|
self.inner.unlock();
|
||||||
@ -812,7 +793,6 @@ where
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -824,7 +804,6 @@ where
|
|||||||
.check_buffer_access(buffer, range, exclusive, queue)
|
.check_buffer_access(buffer, range, exclusive, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -848,7 +827,6 @@ pub struct SecondaryAutoCommandBuffer<P = StandardCommandPoolAlloc> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<P> DeviceOwned for SecondaryAutoCommandBuffer<P> {
|
unsafe impl<P> DeviceOwned for SecondaryAutoCommandBuffer<P> {
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.device()
|
self.inner.device()
|
||||||
}
|
}
|
||||||
@ -858,12 +836,10 @@ unsafe impl<P> SecondaryCommandBuffer for SecondaryAutoCommandBuffer<P>
|
|||||||
where
|
where
|
||||||
P: CommandPoolAlloc,
|
P: CommandPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeCommandBuffer {
|
fn inner(&self) -> &UnsafeCommandBuffer {
|
||||||
self.inner.as_ref()
|
self.inner.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
|
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
|
||||||
match self.submit_state {
|
match self.submit_state {
|
||||||
SubmitState::OneTime {
|
SubmitState::OneTime {
|
||||||
@ -886,7 +862,6 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn unlock(&self) {
|
unsafe fn unlock(&self) {
|
||||||
match self.submit_state {
|
match self.submit_state {
|
||||||
SubmitState::OneTime {
|
SubmitState::OneTime {
|
||||||
@ -902,17 +877,14 @@ where
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
|
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
|
||||||
&self.inheritance_info
|
&self.inheritance_info
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn num_buffers(&self) -> usize {
|
fn num_buffers(&self) -> usize {
|
||||||
self.inner.num_buffers()
|
self.inner.num_buffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn buffer(
|
fn buffer(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
@ -924,12 +896,10 @@ where
|
|||||||
self.inner.buffer(index)
|
self.inner.buffer(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn num_images(&self) -> usize {
|
fn num_images(&self) -> usize {
|
||||||
self.inner.num_images()
|
self.inner.num_images()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image(
|
fn image(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
|
@ -703,7 +703,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdPushConstants` on the builder.
|
/// Calls `vkCmdPushConstants` on the builder.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn push_constants<D>(
|
pub unsafe fn push_constants<D>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pipeline_layout: Arc<PipelineLayout>,
|
pipeline_layout: Arc<PipelineLayout>,
|
||||||
@ -838,7 +837,6 @@ pub struct SyncCommandBufferBuilderBindDescriptorSets<'b> {
|
|||||||
|
|
||||||
impl<'b> SyncCommandBufferBuilderBindDescriptorSets<'b> {
|
impl<'b> SyncCommandBufferBuilderBindDescriptorSets<'b> {
|
||||||
/// Adds a descriptor set to the list.
|
/// Adds a descriptor set to the list.
|
||||||
#[inline]
|
|
||||||
pub fn add(&mut self, descriptor_set: impl Into<DescriptorSetWithOffsets>) {
|
pub fn add(&mut self, descriptor_set: impl Into<DescriptorSetWithOffsets>) {
|
||||||
self.descriptor_sets.push(descriptor_set.into());
|
self.descriptor_sets.push(descriptor_set.into());
|
||||||
}
|
}
|
||||||
@ -1069,7 +1067,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdPushConstants` on the builder.
|
/// Calls `vkCmdPushConstants` on the builder.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn push_constants<D>(
|
pub unsafe fn push_constants<D>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pipeline_layout: &PipelineLayout,
|
pipeline_layout: &PipelineLayout,
|
||||||
@ -1101,7 +1098,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdPushDescriptorSetKHR` on the builder.
|
/// Calls `vkCmdPushDescriptorSetKHR` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn push_descriptor_set<'a>(
|
pub unsafe fn push_descriptor_set<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
pipeline_bind_point: PipelineBindPoint,
|
pipeline_bind_point: PipelineBindPoint,
|
||||||
@ -1162,6 +1158,7 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Prototype for a `vkCmdBindVertexBuffers`.
|
/// Prototype for a `vkCmdBindVertexBuffers`.
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct UnsafeCommandBufferBuilderBindVertexBuffer {
|
pub struct UnsafeCommandBufferBuilderBindVertexBuffer {
|
||||||
// Raw handles of the buffers to bind.
|
// Raw handles of the buffers to bind.
|
||||||
pub raw_buffers: SmallVec<[ash::vk::Buffer; 4]>,
|
pub raw_buffers: SmallVec<[ash::vk::Buffer; 4]>,
|
||||||
@ -1267,7 +1264,6 @@ impl error::Error for BindPushError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for BindPushError {
|
impl Display for BindPushError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -1278,83 +1274,78 @@ impl Display for BindPushError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_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!(
|
Self::DescriptorSetNotCompatible { set_num } => write!(
|
||||||
f,
|
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,
|
set_num,
|
||||||
),
|
),
|
||||||
Self::DescriptorSetNotPush { set_num } => write!(
|
Self::DescriptorSetNotPush { set_num } => write!(
|
||||||
f,
|
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,
|
set_num,
|
||||||
),
|
),
|
||||||
Self::DescriptorSetOutOfRange { set_num, pipeline_layout_set_count } => write!(
|
Self::DescriptorSetOutOfRange {
|
||||||
|
set_num,
|
||||||
|
pipeline_layout_set_count,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
set_num, pipeline_layout_set_count,
|
||||||
),
|
),
|
||||||
Self::IndexBufferMissingUsage => write!(
|
Self::IndexBufferMissingUsage => {
|
||||||
f,
|
write!(f, "an index buffer is missing the `index_buffer` usage")
|
||||||
"an index buffer is missing the `index_buffer` usage",
|
}
|
||||||
),
|
Self::MaxVertexInputBindingsExceeded { .. } => {
|
||||||
Self::MaxVertexInputBindingsExceeded { .. } => write!(
|
write!(f, "the `max_vertex_input_bindings` limit has been exceeded")
|
||||||
f,
|
}
|
||||||
"the `max_vertex_input_bindings` 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::PreviousPipelineColorAttachmentFormatMismatch => write!(
|
Self::PreviousPipelineColorAttachmentFormatMismatch => write!(
|
||||||
f,
|
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!(
|
Self::PreviousPipelineDepthAttachmentFormatMismatch => write!(
|
||||||
f,
|
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!(
|
Self::PreviousPipelineStencilAttachmentFormatMismatch => write!(
|
||||||
f,
|
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 {
|
Self::PushConstantsDataOutOfRange { offset } => write!(
|
||||||
offset,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
offset,
|
||||||
),
|
),
|
||||||
Self::PushConstantsOffsetNotAligned => write!(
|
Self::PushConstantsOffsetNotAligned => {
|
||||||
f,
|
write!(f, "the push constants offset is not a multiple of 4")
|
||||||
"the push constants offset is not a multiple of 4",
|
}
|
||||||
),
|
Self::PushConstantsSizeNotAligned => {
|
||||||
Self::PushConstantsSizeNotAligned => write!(
|
write!(f, "the push constants size is not a multiple of 4")
|
||||||
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::VertexBufferMissingUsage => write!(
|
}
|
||||||
f,
|
|
||||||
"a vertex buffer is missing the `vertex_buffer` usage",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DescriptorSetUpdateError> for BindPushError {
|
impl From<DescriptorSetUpdateError> for BindPushError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DescriptorSetUpdateError) -> Self {
|
fn from(err: DescriptorSetUpdateError) -> Self {
|
||||||
Self::DescriptorSetUpdateError(err)
|
Self::DescriptorSetUpdateError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for BindPushError {
|
impl From<RequirementNotMet> for BindPushError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -30,7 +30,6 @@ use std::{
|
|||||||
/// instance.
|
/// instance.
|
||||||
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||||
/// Opens a command buffer debug label region.
|
/// Opens a command buffer debug label region.
|
||||||
#[inline]
|
|
||||||
pub fn begin_debug_utils_label(
|
pub fn begin_debug_utils_label(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut label_info: DebugUtilsLabel,
|
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
|
/// - 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
|
/// region begun with `begin_debug_utils_label` in the queue, either within this command
|
||||||
/// buffer or a previously submitted one.
|
/// buffer or a previously submitted one.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, DebugUtilsError> {
|
pub unsafe fn end_debug_utils_label(&mut self) -> Result<&mut Self, DebugUtilsError> {
|
||||||
self.validate_end_debug_utils_label()?;
|
self.validate_end_debug_utils_label()?;
|
||||||
|
|
||||||
@ -126,7 +124,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts a command buffer debug label.
|
/// Inserts a command buffer debug label.
|
||||||
#[inline]
|
|
||||||
pub fn insert_debug_utils_label(
|
pub fn insert_debug_utils_label(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut label_info: DebugUtilsLabel,
|
mut label_info: DebugUtilsLabel,
|
||||||
@ -323,7 +320,6 @@ pub enum DebugUtilsError {
|
|||||||
impl Error for DebugUtilsError {}
|
impl Error for DebugUtilsError {}
|
||||||
|
|
||||||
impl Display for DebugUtilsError {
|
impl Display for DebugUtilsError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -334,7 +330,6 @@ impl Display for DebugUtilsError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::NotSupportedByQueueFamily => {
|
Self::NotSupportedByQueueFamily => {
|
||||||
write!(f, "the queue family doesn't allow this operation")
|
write!(f, "the queue family doesn't allow this operation")
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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
|
/// - If there is a graphics pipeline with color blend state bound, `enables.len()` must equal
|
||||||
/// - [`attachments.len()`](crate::pipeline::graphics::color_blend::ColorBlendState::attachments).
|
/// - [`attachments.len()`](crate::pipeline::graphics::color_blend::ColorBlendState::attachments).
|
||||||
#[inline]
|
|
||||||
pub fn set_color_write_enable<I>(&mut self, enables: I) -> &mut Self
|
pub fn set_color_write_enable<I>(&mut self, enables: I) -> &mut Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = bool>,
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_cull_mode(&mut self, cull_mode: CullMode) -> &mut Self {
|
||||||
self.validate_set_cull_mode(cull_mode).unwrap();
|
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.
|
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
||||||
/// - If the [`depth_bias_clamp`](crate::device::Features::depth_bias_clamp)
|
/// - 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.
|
/// feature is not enabled on the device, panics if `clamp` is not 0.0.
|
||||||
#[inline]
|
|
||||||
pub fn set_depth_bias(
|
pub fn set_depth_bias(
|
||||||
&mut self,
|
&mut self,
|
||||||
constant_factor: f32,
|
constant_factor: f32,
|
||||||
@ -271,7 +268,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
|
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_depth_bias_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_depth_bias_enable(enable).unwrap();
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_depth_bounds_test_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_depth_bounds_test_enable(enable).unwrap();
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_depth_compare_op(&mut self, compare_op: CompareOp) -> &mut Self {
|
||||||
self.validate_set_depth_compare_op(compare_op).unwrap();
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_depth_test_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_depth_test_enable(enable).unwrap();
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_depth_write_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_depth_write_enable(enable).unwrap();
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
||||||
#[inline]
|
|
||||||
pub fn set_front_face(&mut self, face: FrontFace) -> &mut Self {
|
pub fn set_front_face(&mut self, face: FrontFace) -> &mut Self {
|
||||||
self.validate_set_front_face(face).unwrap();
|
self.validate_set_front_face(face).unwrap();
|
||||||
|
|
||||||
@ -694,7 +685,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// extension is not enabled on the device.
|
/// extension is not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
||||||
/// - Panics if `factor` is not between 1 and 256 inclusive.
|
/// - Panics if `factor` is not between 1 and 256 inclusive.
|
||||||
#[inline]
|
|
||||||
pub fn set_line_stipple(&mut self, factor: u32, pattern: u16) -> &mut Self {
|
pub fn set_line_stipple(&mut self, factor: u32, pattern: u16) -> &mut Self {
|
||||||
self.validate_set_line_stipple(factor, pattern).unwrap();
|
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)
|
/// [`extended_dynamic_state2_logic_op`](crate::device::Features::extended_dynamic_state2_logic_op)
|
||||||
/// feature is not enabled on the device.
|
/// feature is not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_logic_op(&mut self, logic_op: LogicOp) -> &mut Self {
|
||||||
self.validate_set_logic_op(logic_op).unwrap();
|
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
|
/// - Panics if `num` is greater than the
|
||||||
/// [`max_tessellation_patch_size`](crate::device::Properties::max_tessellation_patch_size)
|
/// [`max_tessellation_patch_size`](crate::device::Properties::max_tessellation_patch_size)
|
||||||
/// property of the device.
|
/// property of the device.
|
||||||
#[inline]
|
|
||||||
pub fn set_patch_control_points(&mut self, num: u32) -> &mut Self {
|
pub fn set_patch_control_points(&mut self, num: u32) -> &mut Self {
|
||||||
self.validate_set_patch_control_points(num).unwrap();
|
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
|
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_primitive_restart_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_primitive_restart_enable(enable).unwrap();
|
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.
|
/// enabled, panics if `topology` is a `WithAdjacency` topology.
|
||||||
/// - If the [`tessellation_shader`](crate::device::Features::tessellation_shader) feature is
|
/// - If the [`tessellation_shader`](crate::device::Features::tessellation_shader) feature is
|
||||||
/// not enabled, panics if `topology` is `PatchList`.
|
/// not enabled, panics if `topology` is `PatchList`.
|
||||||
#[inline]
|
|
||||||
pub fn set_primitive_topology(&mut self, topology: PrimitiveTopology) -> &mut Self {
|
pub fn set_primitive_topology(&mut self, topology: PrimitiveTopology) -> &mut Self {
|
||||||
self.validate_set_primitive_topology(topology).unwrap();
|
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
|
/// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_rasterizer_discard_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_rasterizer_discard_enable(enable).unwrap();
|
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.
|
/// [`max_viewports`](crate::device::Properties::max_viewports) device property.
|
||||||
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
|
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
|
||||||
/// panics if more than 1 scissor is provided.
|
/// panics if more than 1 scissor is provided.
|
||||||
#[inline]
|
|
||||||
pub fn set_scissor_with_count(
|
pub fn set_scissor_with_count(
|
||||||
&mut self,
|
&mut self,
|
||||||
scissors: impl IntoIterator<Item = Scissor>,
|
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
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
||||||
#[inline]
|
|
||||||
pub fn set_stencil_op(
|
pub fn set_stencil_op(
|
||||||
&mut self,
|
&mut self,
|
||||||
faces: StencilFaces,
|
faces: StencilFaces,
|
||||||
@ -1410,7 +1393,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
/// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature is
|
||||||
/// not enabled on the device.
|
/// not enabled on the device.
|
||||||
/// - Panics if the currently bound graphics pipeline already contains this state internally.
|
/// - 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 {
|
pub fn set_stencil_test_enable(&mut self, enable: bool) -> &mut Self {
|
||||||
self.validate_set_stencil_test_enable(enable).unwrap();
|
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.
|
/// [`max_viewports`](crate::device::Properties::max_viewports) device property.
|
||||||
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
|
/// - If the [`multi_viewport`](crate::device::Features::multi_viewport) feature is not enabled,
|
||||||
/// panics if more than 1 viewport is provided.
|
/// panics if more than 1 viewport is provided.
|
||||||
#[inline]
|
|
||||||
pub fn set_viewport_with_count(
|
pub fn set_viewport_with_count(
|
||||||
&mut self,
|
&mut self,
|
||||||
viewports: impl IntoIterator<Item = Viewport>,
|
viewports: impl IntoIterator<Item = Viewport>,
|
||||||
@ -1665,7 +1646,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
|
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// 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>) {
|
pub unsafe fn set_color_write_enable(&mut self, enables: impl IntoIterator<Item = bool>) {
|
||||||
struct Cmd<I> {
|
struct Cmd<I> {
|
||||||
enables: Mutex<Option<I>>,
|
enables: Mutex<Option<I>>,
|
||||||
@ -1874,7 +1854,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetDiscardRectangle` on the builder.
|
/// Calls `vkCmdSetDiscardRectangle` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_discard_rectangle(
|
pub unsafe fn set_discard_rectangle(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_rectangle: u32,
|
first_rectangle: u32,
|
||||||
@ -2260,7 +2239,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetScissor` on the builder.
|
/// Calls `vkCmdSetScissor` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_scissor(
|
pub unsafe fn set_scissor(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_scissor: u32,
|
first_scissor: u32,
|
||||||
@ -2297,7 +2275,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
|
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// 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>) {
|
pub unsafe fn set_scissor_with_count(&mut self, scissors: impl IntoIterator<Item = Scissor>) {
|
||||||
struct Cmd {
|
struct Cmd {
|
||||||
scissors: Mutex<SmallVec<[Scissor; 2]>>,
|
scissors: Mutex<SmallVec<[Scissor; 2]>>,
|
||||||
@ -2323,7 +2300,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetViewport` on the builder.
|
/// Calls `vkCmdSetViewport` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_viewport(
|
pub unsafe fn set_viewport(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_viewport: u32,
|
first_viewport: u32,
|
||||||
@ -2360,7 +2336,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
|
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_viewport_with_count(
|
pub unsafe fn set_viewport_with_count(
|
||||||
&mut self,
|
&mut self,
|
||||||
viewports: impl IntoIterator<Item = Viewport>,
|
viewports: impl IntoIterator<Item = Viewport>,
|
||||||
@ -2398,7 +2373,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
|
/// Calls `vkCmdSetColorWriteEnableEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// 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>) {
|
pub unsafe fn set_color_write_enable(&mut self, enables: impl IntoIterator<Item = bool>) {
|
||||||
debug_assert!(self.device.enabled_extensions().ext_color_write_enable);
|
debug_assert!(self.device.enabled_extensions().ext_color_write_enable);
|
||||||
|
|
||||||
@ -2522,7 +2496,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetDiscardRectangleEXT` on the builder.
|
/// Calls `vkCmdSetDiscardRectangleEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_discard_rectangle(
|
pub unsafe fn set_discard_rectangle(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_rectangle: u32,
|
first_rectangle: u32,
|
||||||
@ -2722,7 +2695,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetScissor` on the builder.
|
/// Calls `vkCmdSetScissor` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_scissor(
|
pub unsafe fn set_scissor(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_scissor: u32,
|
first_scissor: u32,
|
||||||
@ -2748,7 +2720,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
|
/// Calls `vkCmdSetScissorWithCountEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// 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>) {
|
pub unsafe fn set_scissor_with_count(&mut self, scissors: impl IntoIterator<Item = Scissor>) {
|
||||||
let scissors = scissors
|
let scissors = scissors
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -2780,7 +2751,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetViewport` on the builder.
|
/// Calls `vkCmdSetViewport` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_viewport(
|
pub unsafe fn set_viewport(
|
||||||
&mut self,
|
&mut self,
|
||||||
first_viewport: u32,
|
first_viewport: u32,
|
||||||
@ -2806,7 +2776,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
|
/// Calls `vkCmdSetViewportWithCountEXT` on the builder.
|
||||||
///
|
///
|
||||||
/// If the list is empty then the command is automatically ignored.
|
/// If the list is empty then the command is automatically ignored.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn set_viewport_with_count(
|
pub unsafe fn set_viewport_with_count(
|
||||||
&mut self,
|
&mut self,
|
||||||
viewports: impl IntoIterator<Item = Viewport>,
|
viewports: impl IntoIterator<Item = Viewport>,
|
||||||
@ -2880,7 +2849,6 @@ enum SetDynamicStateError {
|
|||||||
impl Error for SetDynamicStateError {}
|
impl Error for SetDynamicStateError {}
|
||||||
|
|
||||||
impl Display for SetDynamicStateError {
|
impl Display for SetDynamicStateError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -2891,45 +2859,42 @@ impl Display for SetDynamicStateError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::FactorOutOfRange => write!(
|
Self::FactorOutOfRange => write!(
|
||||||
f,
|
f,
|
||||||
"the provided `factor` is not between 1 and 256 inclusive",
|
"the provided `factor` is not between 1 and 256 inclusive",
|
||||||
),
|
),
|
||||||
Self::MaxDiscardRectanglesExceeded { .. } => write!(
|
Self::MaxDiscardRectanglesExceeded { .. } => {
|
||||||
f,
|
write!(f, "the `max_discard_rectangles` limit has been exceeded")
|
||||||
"the `max_discard_rectangles` limit has been exceeded",
|
}
|
||||||
),
|
|
||||||
Self::MaxTessellationPatchSizeExceeded { .. } => write!(
|
Self::MaxTessellationPatchSizeExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the `max_tessellation_patch_size` limit has been exceeded",
|
"the `max_tessellation_patch_size` limit has been exceeded",
|
||||||
),
|
),
|
||||||
Self::MaxViewportsExceeded { .. } => write!(
|
Self::MaxViewportsExceeded { .. } => {
|
||||||
f,
|
write!(f, "the `max_viewports` limit has been exceeded")
|
||||||
"the `max_viewports` limit has been exceeded",
|
}
|
||||||
),
|
Self::NotSupportedByQueueFamily => {
|
||||||
Self::NotSupportedByQueueFamily => write!(
|
write!(f, "the queue family doesn't allow this operation")
|
||||||
f,
|
}
|
||||||
"the queue family doesn't allow this operation",
|
|
||||||
),
|
|
||||||
Self::PipelineColorBlendAttachmentCountMismatch {
|
Self::PipelineColorBlendAttachmentCountMismatch {
|
||||||
provided_count,
|
provided_count,
|
||||||
required_count,
|
required_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
provided_count, required_count,
|
||||||
),
|
),
|
||||||
Self::PipelineHasFixedState => write!(
|
Self::PipelineHasFixedState => write!(
|
||||||
f,
|
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 {
|
impl From<RequirementNotMet> for SetDynamicStateError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -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 `layer_count` is greater than 1, the blit will happen between each individual layer as
|
||||||
/// if they were separate images.
|
/// if they were separate images.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the source or the destination was not created with `device`.
|
/// - 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> {
|
pub fn blit_image(&mut self, blit_image_info: BlitImageInfo) -> Result<&mut Self, CopyError> {
|
||||||
self.validate_blit_image(&blit_image_info)?;
|
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.
|
/// Clears a color image with a specific value.
|
||||||
#[inline]
|
|
||||||
pub fn clear_color_image(
|
pub fn clear_color_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
clear_info: ClearColorImageInfo,
|
clear_info: ClearColorImageInfo,
|
||||||
@ -714,7 +712,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clears a depth/stencil image with a specific value.
|
/// Clears a depth/stencil image with a specific value.
|
||||||
#[inline]
|
|
||||||
pub fn clear_depth_stencil_image(
|
pub fn clear_depth_stencil_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
clear_info: ClearDepthStencilImageInfo,
|
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
|
/// - Panics if `src_image` or `dst_image` were not created from the same device
|
||||||
/// as `self`.
|
/// as `self`.
|
||||||
#[inline]
|
|
||||||
pub fn resolve_image(
|
pub fn resolve_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
resolve_image_info: ResolveImageInfo,
|
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
|
/// 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.
|
/// usage of the command anyway.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn clear_color_image(
|
pub unsafe fn clear_color_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
clear_info: ClearColorImageInfo,
|
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
|
/// 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.
|
/// usage of the command anyway.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn clear_depth_stencil_image(
|
pub unsafe fn clear_depth_stencil_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
clear_info: ClearDepthStencilImageInfo,
|
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
|
/// 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.
|
/// usage of the command anyway.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn clear_color_image(&mut self, clear_info: &ClearColorImageInfo) {
|
pub unsafe fn clear_color_image(&mut self, clear_info: &ClearColorImageInfo) {
|
||||||
let &ClearColorImageInfo {
|
let &ClearColorImageInfo {
|
||||||
ref image,
|
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
|
/// 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.
|
/// usage of the command anyway.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn clear_depth_stencil_image(&mut self, clear_info: &ClearDepthStencilImageInfo) {
|
pub unsafe fn clear_depth_stencil_image(&mut self, clear_info: &ClearDepthStencilImageInfo) {
|
||||||
let &ClearDepthStencilImageInfo {
|
let &ClearDepthStencilImageInfo {
|
||||||
ref image,
|
ref image,
|
||||||
|
@ -124,7 +124,8 @@ pub enum CopyError {
|
|||||||
max: DeviceSize,
|
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,
|
DepthStencilNotSupportedByQueueFamily,
|
||||||
|
|
||||||
/// The image extent of a region is not a multiple of the required image alignment.
|
/// 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 {
|
impl Error for CopyError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
||||||
@ -285,11 +285,9 @@ impl Error for CopyError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CopyError {
|
impl Display for CopyError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -298,21 +296,20 @@ impl Display for CopyError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::ForbiddenInsideRenderPass => {
|
Self::ForbiddenInsideRenderPass => {
|
||||||
write!(f, "operation forbidden inside of a render pass")
|
write!(f, "operation forbidden inside of a render pass")
|
||||||
}
|
}
|
||||||
Self::NotSupportedByQueueFamily => {
|
Self::NotSupportedByQueueFamily => {
|
||||||
write!(f, "the queue family doesn't allow this operation")
|
write!(f, "the queue family doesn't allow this operation")
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::ArrayLayerCountMismatch {
|
Self::ArrayLayerCountMismatch {
|
||||||
region_index,
|
region_index,
|
||||||
src_layer_count,
|
src_layer_count,
|
||||||
dst_layer_count,
|
dst_layer_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
region_index, src_layer_count, dst_layer_count,
|
||||||
),
|
),
|
||||||
Self::ArrayLayersOutOfRange {
|
Self::ArrayLayersOutOfRange {
|
||||||
@ -322,7 +319,8 @@ impl Display for CopyError {
|
|||||||
image_array_layers,
|
image_array_layers,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
array_layers_range_end, resource, region_index, resource, image_array_layers,
|
||||||
),
|
),
|
||||||
Self::AspectsMismatch {
|
Self::AspectsMismatch {
|
||||||
@ -331,7 +329,8 @@ impl Display for CopyError {
|
|||||||
dst_aspects,
|
dst_aspects,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
region_index, src_aspects, dst_aspects,
|
||||||
),
|
),
|
||||||
Self::AspectsNotAllowed {
|
Self::AspectsNotAllowed {
|
||||||
@ -341,7 +340,8 @@ impl Display for CopyError {
|
|||||||
allowed_aspects,
|
allowed_aspects,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
aspects, resource, region_index, resource, allowed_aspects,
|
||||||
),
|
),
|
||||||
Self::BufferImageHeightNotAligned {
|
Self::BufferImageHeightNotAligned {
|
||||||
@ -351,7 +351,8 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, image_height, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
Self::BufferRowLengthTooLarge {
|
Self::BufferRowLengthTooLarge {
|
||||||
@ -360,7 +361,8 @@ impl Display for CopyError {
|
|||||||
buffer_row_length,
|
buffer_row_length,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, buffer_row_length, region_index,
|
||||||
),
|
),
|
||||||
Self::BufferImageHeightTooSmall {
|
Self::BufferImageHeightTooSmall {
|
||||||
@ -370,7 +372,8 @@ impl Display for CopyError {
|
|||||||
min,
|
min,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, image_height, region_index, resource, min,
|
||||||
),
|
),
|
||||||
Self::BufferRowLengthNotAligned {
|
Self::BufferRowLengthNotAligned {
|
||||||
@ -380,7 +383,8 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, row_length, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
Self::BufferRowLengthTooSmall {
|
Self::BufferRowLengthTooSmall {
|
||||||
@ -390,20 +394,19 @@ impl Display for CopyError {
|
|||||||
min,
|
min,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, row_length, region_index, resource, min,
|
||||||
),
|
),
|
||||||
Self::DataTooLarge {
|
Self::DataTooLarge { size, max } => write!(
|
||||||
size,
|
|
||||||
max,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"the provided data has a size ({}) greater than the maximum allowed ({})",
|
"the provided data has a size ({}) greater than the maximum allowed ({})",
|
||||||
size, max,
|
size, max,
|
||||||
),
|
),
|
||||||
Self::DepthStencilNotSupportedByQueueFamily => write!(
|
Self::DepthStencilNotSupportedByQueueFamily => write!(
|
||||||
f,
|
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 {
|
Self::ExtentNotAlignedForImage {
|
||||||
resource,
|
resource,
|
||||||
@ -412,21 +415,19 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, extent, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
Self::FilterNotSupportedForImageType => write!(
|
Self::FilterNotSupportedForImageType => write!(
|
||||||
f,
|
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!(
|
Self::FilterNotSupportedByFormat => write!(
|
||||||
f,
|
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 {
|
Self::FormatNotSupported { resource, format } => write!(
|
||||||
resource,
|
|
||||||
format,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"the format of the {} image ({:?}) is not supported for this operation",
|
"the format of the {} image ({:?}) is not supported for this operation",
|
||||||
resource, format,
|
resource, format,
|
||||||
@ -436,7 +437,8 @@ impl Display for CopyError {
|
|||||||
dst_format,
|
dst_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
src_format, dst_format,
|
||||||
),
|
),
|
||||||
Self::FormatsNotCompatible {
|
Self::FormatsNotCompatible {
|
||||||
@ -444,7 +446,8 @@ impl Display for CopyError {
|
|||||||
dst_format,
|
dst_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
src_format, dst_format,
|
||||||
),
|
),
|
||||||
Self::ImageLayoutInvalid {
|
Self::ImageLayoutInvalid {
|
||||||
@ -462,7 +465,8 @@ impl Display for CopyError {
|
|||||||
image_mip_levels,
|
image_mip_levels,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
mip_levels_range_end, resource, region_index, resource, image_mip_levels,
|
||||||
),
|
),
|
||||||
Self::MissingFormatFeature {
|
Self::MissingFormatFeature {
|
||||||
@ -484,7 +488,8 @@ impl Display for CopyError {
|
|||||||
aspects,
|
aspects,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, region_index, aspects, resource,
|
||||||
),
|
),
|
||||||
Self::OffsetNotAlignedForBuffer {
|
Self::OffsetNotAlignedForBuffer {
|
||||||
@ -494,7 +499,8 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, offset, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
Self::OffsetNotAlignedForImage {
|
Self::OffsetNotAlignedForImage {
|
||||||
@ -504,7 +510,8 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, offset, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
Self::OffsetsInvalidForImageType {
|
Self::OffsetsInvalidForImageType {
|
||||||
@ -513,7 +520,8 @@ impl Display for CopyError {
|
|||||||
offsets,
|
offsets,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, offsets, region_index, resource,
|
||||||
),
|
),
|
||||||
Self::OverlappingRegions {
|
Self::OverlappingRegions {
|
||||||
@ -531,7 +539,9 @@ impl Display for CopyError {
|
|||||||
dst_image_layout,
|
dst_image_layout,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
src_region_index, dst_region_index, src_image_layout, dst_image_layout,
|
||||||
),
|
),
|
||||||
Self::RegionOutOfBufferBounds {
|
Self::RegionOutOfBufferBounds {
|
||||||
@ -541,7 +551,8 @@ impl Display for CopyError {
|
|||||||
buffer_size,
|
buffer_size,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, offset_range_end, region_index, resource, buffer_size,
|
||||||
),
|
),
|
||||||
Self::RegionOutOfImageBounds {
|
Self::RegionOutOfImageBounds {
|
||||||
@ -551,7 +562,8 @@ impl Display for CopyError {
|
|||||||
subresource_extent,
|
subresource_extent,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, offset_range_end, region_index, resource, subresource_extent,
|
||||||
),
|
),
|
||||||
Self::SampleCountInvalid {
|
Self::SampleCountInvalid {
|
||||||
@ -560,7 +572,8 @@ impl Display for CopyError {
|
|||||||
allowed_sample_counts,
|
allowed_sample_counts,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, sample_count, allowed_sample_counts,
|
||||||
),
|
),
|
||||||
Self::SampleCountMismatch {
|
Self::SampleCountMismatch {
|
||||||
@ -568,7 +581,8 @@ impl Display for CopyError {
|
|||||||
dst_sample_count,
|
dst_sample_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
src_sample_count, dst_sample_count,
|
||||||
),
|
),
|
||||||
Self::SizeNotAlignedForBuffer {
|
Self::SizeNotAlignedForBuffer {
|
||||||
@ -578,7 +592,8 @@ impl Display for CopyError {
|
|||||||
required_alignment,
|
required_alignment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
resource, size, region_index, resource, required_alignment,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -586,14 +601,12 @@ impl Display for CopyError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyncCommandBufferBuilderError> for CopyError {
|
impl From<SyncCommandBufferBuilderError> for CopyError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
||||||
Self::SyncCommandBufferBuilderError(err)
|
Self::SyncCommandBufferBuilderError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for CopyError {
|
impl From<RequirementNotMet> for CopyError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -610,7 +623,6 @@ pub enum CopyErrorResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CopyErrorResource {
|
impl Display for CopyErrorResource {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::Source => write!(f, "source"),
|
Self::Source => write!(f, "source"),
|
||||||
|
@ -55,7 +55,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// A compute pipeline must have been bound using
|
/// A compute pipeline must have been bound using
|
||||||
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
|
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
|
||||||
/// pipeline, such as descriptor sets, must have been set beforehand.
|
/// pipeline, such as descriptor sets, must have been set beforehand.
|
||||||
#[inline]
|
|
||||||
pub fn dispatch(
|
pub fn dispatch(
|
||||||
&mut self,
|
&mut self,
|
||||||
group_counts: [u32; 3],
|
group_counts: [u32; 3],
|
||||||
@ -116,7 +115,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// A compute pipeline must have been bound using
|
/// A compute pipeline must have been bound using
|
||||||
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
|
/// [`bind_pipeline_compute`](Self::bind_pipeline_compute). Any resources used by the compute
|
||||||
/// pipeline, such as descriptor sets, must have been set beforehand.
|
/// pipeline, such as descriptor sets, must have been set beforehand.
|
||||||
#[inline]
|
|
||||||
pub fn dispatch_indirect<Inb>(
|
pub fn dispatch_indirect<Inb>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indirect_buffer: Arc<Inb>,
|
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
|
/// 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
|
/// 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.
|
/// instance ranges must be in range of the bound vertex buffers.
|
||||||
#[inline]
|
|
||||||
pub fn draw(
|
pub fn draw(
|
||||||
&mut self,
|
&mut self,
|
||||||
vertex_count: u32,
|
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
|
/// 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
|
/// ranges of each `DrawIndirectCommand` in the indirect buffer must be in range of the bound
|
||||||
/// vertex buffers.
|
/// vertex buffers.
|
||||||
#[inline]
|
|
||||||
pub fn draw_indirect<Inb>(
|
pub fn draw_indirect<Inb>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indirect_buffer: Arc<Inb>,
|
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
|
/// 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
|
/// 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.
|
/// must be in range of the bound vertex buffers.
|
||||||
#[inline]
|
|
||||||
pub fn draw_indexed(
|
pub fn draw_indexed(
|
||||||
&mut self,
|
&mut self,
|
||||||
index_count: u32,
|
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
|
/// 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
|
/// each `DrawIndexedIndirectCommand` in the indirect buffer must be in range of the bound
|
||||||
/// vertex buffers.
|
/// vertex buffers.
|
||||||
#[inline]
|
|
||||||
pub fn draw_indexed_indirect<Inb>(
|
pub fn draw_indexed_indirect<Inb>(
|
||||||
&mut self,
|
&mut self,
|
||||||
indirect_buffer: Arc<Inb>,
|
indirect_buffer: Arc<Inb>,
|
||||||
@ -2345,7 +2339,8 @@ pub enum PipelineExecutionError {
|
|||||||
/// An indexed draw command was recorded, but no index buffer was bound.
|
/// An indexed draw command was recorded, but no index buffer was bound.
|
||||||
IndexBufferNotBound,
|
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 {
|
IndexBufferRangeOutOfBounds {
|
||||||
highest_index: u32,
|
highest_index: u32,
|
||||||
max_index_count: u32,
|
max_index_count: u32,
|
||||||
@ -2459,7 +2454,6 @@ pub enum PipelineExecutionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for PipelineExecutionError {
|
impl Error for PipelineExecutionError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
||||||
@ -2470,11 +2464,9 @@ impl Error for PipelineExecutionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PipelineExecutionError {
|
impl Display for PipelineExecutionError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -2483,17 +2475,21 @@ impl Display for PipelineExecutionError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::DescriptorResourceInvalid {
|
||||||
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 {
|
|
||||||
set_num,
|
set_num,
|
||||||
|
binding_num,
|
||||||
|
index,
|
||||||
|
..
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
set_num,
|
||||||
),
|
),
|
||||||
Self::DynamicColorWriteEnableNotEnoughValues {
|
Self::DynamicColorWriteEnableNotEnoughValues {
|
||||||
@ -2501,23 +2497,24 @@ impl Display for PipelineExecutionError {
|
|||||||
attachment_count,
|
attachment_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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 ({})",
|
"the bound pipeline uses a dynamic color write enable setting, but the number of \
|
||||||
color_write_enable_count,
|
provided enable values ({}) is less than the number of attachments in the current \
|
||||||
attachment_count,
|
render subpass ({})",
|
||||||
|
color_write_enable_count, attachment_count,
|
||||||
),
|
),
|
||||||
Self::DynamicPrimitiveTopologyClassMismatch {
|
Self::DynamicPrimitiveTopologyClassMismatch {
|
||||||
provided_class,
|
provided_class,
|
||||||
required_class,
|
required_class,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
provided_class, required_class,
|
||||||
),
|
),
|
||||||
Self::DynamicPrimitiveTopologyInvalid {
|
Self::DynamicPrimitiveTopologyInvalid { topology } => write!(
|
||||||
topology,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
topology,
|
||||||
),
|
),
|
||||||
Self::DynamicStateNotSet { dynamic_state } => write!(
|
Self::DynamicStateNotSet { dynamic_state } => write!(
|
||||||
@ -2530,18 +2527,16 @@ impl Display for PipelineExecutionError {
|
|||||||
scissor_count,
|
scissor_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the bound pipeline uses a dynamic scissor and/or viewport count, but the scissor count ({}) does not match the viewport count ({})",
|
"the bound pipeline uses a dynamic scissor and/or viewport count, but the scissor \
|
||||||
scissor_count,
|
count ({}) does not match the viewport count ({})",
|
||||||
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::ForbiddenInsideRenderPass => {
|
||||||
|
write!(f, "operation forbidden inside a render pass")
|
||||||
|
}
|
||||||
|
Self::ForbiddenOutsideRenderPass => {
|
||||||
|
write!(f, "operation forbidden outside a render pass")
|
||||||
|
}
|
||||||
Self::ForbiddenWithSubpassContents { subpass_contents } => write!(
|
Self::ForbiddenWithSubpassContents { subpass_contents } => write!(
|
||||||
f,
|
f,
|
||||||
"operation forbidden inside a render subpass with contents {:?}",
|
"operation forbidden inside a render subpass with contents {:?}",
|
||||||
@ -2556,9 +2551,9 @@ impl Display for PipelineExecutionError {
|
|||||||
max_index_count,
|
max_index_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"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 \
|
||||||
highest_index,
|
bound index buffer ({})",
|
||||||
max_index_count,
|
highest_index, max_index_count,
|
||||||
),
|
),
|
||||||
Self::IndirectBufferMissingUsage => write!(
|
Self::IndirectBufferMissingUsage => write!(
|
||||||
f,
|
f,
|
||||||
@ -2568,24 +2563,23 @@ impl Display for PipelineExecutionError {
|
|||||||
f,
|
f,
|
||||||
"the `max_compute_work_group_count` limit has been exceeded",
|
"the `max_compute_work_group_count` limit has been exceeded",
|
||||||
),
|
),
|
||||||
Self::MaxDrawIndirectCountExceeded { .. } => write!(
|
Self::MaxDrawIndirectCountExceeded { .. } => {
|
||||||
f,
|
write!(f, "the `max_draw_indirect_count` limit has been exceeded")
|
||||||
"the `max_draw_indirect_count` limit has been exceeded",
|
}
|
||||||
),
|
|
||||||
Self::MaxMultiviewInstanceIndexExceeded { .. } => write!(
|
Self::MaxMultiviewInstanceIndexExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the `max_multiview_instance_index` limit has been exceeded",
|
"the `max_multiview_instance_index` limit has been exceeded",
|
||||||
),
|
),
|
||||||
Self::NotSupportedByQueueFamily => write!(
|
Self::NotSupportedByQueueFamily => {
|
||||||
f,
|
write!(f, "the queue family doesn't allow this operation")
|
||||||
"the queue family doesn't allow this operation",
|
}
|
||||||
),
|
|
||||||
Self::PipelineColorAttachmentCountMismatch {
|
Self::PipelineColorAttachmentCountMismatch {
|
||||||
pipeline_count,
|
pipeline_count,
|
||||||
required_count,
|
required_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
pipeline_count, required_count,
|
||||||
),
|
),
|
||||||
Self::PipelineColorAttachmentFormatMismatch {
|
Self::PipelineColorAttachmentFormatMismatch {
|
||||||
@ -2594,7 +2588,8 @@ impl Display for PipelineExecutionError {
|
|||||||
required_format,
|
required_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
color_attachment_index, pipeline_format, required_format,
|
||||||
),
|
),
|
||||||
Self::PipelineDepthAttachmentFormatMismatch {
|
Self::PipelineDepthAttachmentFormatMismatch {
|
||||||
@ -2602,12 +2597,14 @@ impl Display for PipelineExecutionError {
|
|||||||
required_format,
|
required_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
pipeline_format, required_format,
|
||||||
),
|
),
|
||||||
Self::PipelineLayoutNotCompatible => write!(
|
Self::PipelineLayoutNotCompatible => write!(
|
||||||
f,
|
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!(
|
Self::PipelineNotBound => write!(
|
||||||
f,
|
f,
|
||||||
@ -2615,27 +2612,27 @@ impl Display for PipelineExecutionError {
|
|||||||
),
|
),
|
||||||
Self::PipelineRenderPassNotCompatible => write!(
|
Self::PipelineRenderPassNotCompatible => write!(
|
||||||
f,
|
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!(
|
Self::PipelineRenderPassTypeMismatch => write!(
|
||||||
f,
|
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 {
|
Self::PipelineSubpassMismatch { pipeline, current } => write!(
|
||||||
pipeline,
|
|
||||||
current,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"the bound graphics pipeline uses a render subpass index ({}) that doesn't match the currently active subpass index ({})",
|
"the bound graphics pipeline uses a render subpass index ({}) that doesn't match \
|
||||||
pipeline,
|
the currently active subpass index ({})",
|
||||||
current,
|
pipeline, current,
|
||||||
),
|
),
|
||||||
Self::PipelineStencilAttachmentFormatMismatch {
|
Self::PipelineStencilAttachmentFormatMismatch {
|
||||||
pipeline_format,
|
pipeline_format,
|
||||||
required_format,
|
required_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
pipeline_format, required_format,
|
||||||
),
|
),
|
||||||
Self::PipelineViewMaskMismatch {
|
Self::PipelineViewMaskMismatch {
|
||||||
@ -2643,7 +2640,8 @@ impl Display for PipelineExecutionError {
|
|||||||
required_view_mask,
|
required_view_mask,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
pipeline_view_mask, required_view_mask,
|
||||||
),
|
),
|
||||||
Self::PushConstantsNotCompatible => write!(
|
Self::PushConstantsNotCompatible => write!(
|
||||||
@ -2654,11 +2652,10 @@ impl Display for PipelineExecutionError {
|
|||||||
f,
|
f,
|
||||||
"not all push constants used by the pipeline have been set",
|
"not all push constants used by the pipeline have been set",
|
||||||
),
|
),
|
||||||
Self::VertexBufferNotBound {
|
Self::VertexBufferNotBound { binding_num } => write!(
|
||||||
binding_num,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
binding_num,
|
||||||
),
|
),
|
||||||
Self::VertexBufferInstanceRangeOutOfBounds {
|
Self::VertexBufferInstanceRangeOutOfBounds {
|
||||||
@ -2666,7 +2663,8 @@ impl Display for PipelineExecutionError {
|
|||||||
instances_in_buffers,
|
instances_in_buffers,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
instances_needed, instances_in_buffers,
|
||||||
),
|
),
|
||||||
Self::VertexBufferVertexRangeOutOfBounds {
|
Self::VertexBufferVertexRangeOutOfBounds {
|
||||||
@ -2674,7 +2672,8 @@ impl Display for PipelineExecutionError {
|
|||||||
vertices_in_buffers,
|
vertices_in_buffers,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
vertices_needed, vertices_in_buffers,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -2682,7 +2681,6 @@ impl Display for PipelineExecutionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyncCommandBufferBuilderError> for PipelineExecutionError {
|
impl From<SyncCommandBufferBuilderError> for PipelineExecutionError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
||||||
Self::SyncCommandBufferBuilderError(err)
|
Self::SyncCommandBufferBuilderError(err)
|
||||||
}
|
}
|
||||||
@ -2734,40 +2732,41 @@ impl Error for DescriptorResourceInvalidError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DescriptorResourceInvalidError {
|
impl Display for DescriptorResourceInvalidError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::ImageViewFormatMismatch { provided, required } => write!(
|
Self::ImageViewFormatMismatch { provided, required } => write!(
|
||||||
f,
|
f,
|
||||||
"the format of the bound image view ({:?}) does not match what the pipeline requires ({:?})",
|
"the format of the bound image view ({:?}) does not match what the pipeline \
|
||||||
provided, required
|
requires ({:?})",
|
||||||
|
provided, required,
|
||||||
),
|
),
|
||||||
Self::ImageViewMultisampledMismatch { provided, required } => write!(
|
Self::ImageViewMultisampledMismatch { provided, required } => write!(
|
||||||
f,
|
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,
|
provided, required,
|
||||||
),
|
),
|
||||||
Self::ImageViewScalarTypeMismatch { provided, required } => write!(
|
Self::ImageViewScalarTypeMismatch { provided, required } => write!(
|
||||||
f,
|
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,
|
provided, required,
|
||||||
),
|
),
|
||||||
Self::ImageViewTypeMismatch { provided, required } => write!(
|
Self::ImageViewTypeMismatch { provided, required } => write!(
|
||||||
f,
|
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,
|
provided, required,
|
||||||
),
|
),
|
||||||
Self::Missing => write!(
|
Self::Missing => write!(f, "no resource was bound"),
|
||||||
f,
|
|
||||||
"no resource was bound",
|
|
||||||
),
|
|
||||||
Self::SamplerImageViewIncompatible { .. } => write!(
|
Self::SamplerImageViewIncompatible { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the bound sampler samples an image view that is not compatible with that sampler",
|
"the bound sampler samples an image view that is not compatible with that sampler",
|
||||||
),
|
),
|
||||||
Self::SamplerCompareMismatch { provided, required } => write!(
|
Self::SamplerCompareMismatch { provided, required } => write!(
|
||||||
f,
|
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,
|
provided, required,
|
||||||
),
|
),
|
||||||
Self::SamplerUnnormalizedCoordinatesNotAllowed => write!(
|
Self::SamplerUnnormalizedCoordinatesNotAllowed => write!(
|
||||||
@ -2784,11 +2783,13 @@ impl Display for DescriptorResourceInvalidError {
|
|||||||
),
|
),
|
||||||
Self::StorageReadWithoutFormatNotSupported => write!(
|
Self::StorageReadWithoutFormatNotSupported => write!(
|
||||||
f,
|
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!(
|
Self::StorageWriteWithoutFormatNotSupported => write!(
|
||||||
f,
|
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",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.
|
/// The query will be active until [`end_query`](Self::end_query) is called for the same query.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # 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(
|
pub unsafe fn begin_query(
|
||||||
&mut self,
|
&mut self,
|
||||||
query_pool: Arc<QueryPool>,
|
query_pool: Arc<QueryPool>,
|
||||||
@ -211,7 +213,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// Writes a timestamp to a timestamp query.
|
/// Writes a timestamp to a timestamp query.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # 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(
|
pub unsafe fn write_timestamp(
|
||||||
&mut self,
|
&mut self,
|
||||||
query_pool: Arc<QueryPool>,
|
query_pool: Arc<QueryPool>,
|
||||||
@ -704,7 +708,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdCopyQueryPoolResults` on the builder.
|
/// Calls `vkCmdCopyQueryPoolResults` on the builder.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn copy_query_pool_results<D, T>(
|
pub unsafe fn copy_query_pool_results<D, T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
queries: QueriesRange<'_>,
|
queries: QueriesRange<'_>,
|
||||||
@ -805,14 +808,9 @@ pub enum QueryError {
|
|||||||
impl Error for QueryError {}
|
impl Error for QueryError {}
|
||||||
|
|
||||||
impl Display for QueryError {
|
impl Display for QueryError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(_) => write!(
|
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
||||||
f,
|
|
||||||
"a SyncCommandBufferBuilderError",
|
|
||||||
),
|
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -821,7 +819,6 @@ impl Display for QueryError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::BufferTooSmall { .. } => {
|
Self::BufferTooSmall { .. } => {
|
||||||
write!(f, "the buffer is too small for the copy operation")
|
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::OutOfRange => write!(f, "the provided query index is not valid for this pool"),
|
||||||
Self::OutOfRangeMultiview => write!(
|
Self::OutOfRangeMultiview => write!(
|
||||||
f,
|
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!(
|
Self::QueryIsActive => write!(
|
||||||
f,
|
f,
|
||||||
@ -861,14 +859,12 @@ impl Display for QueryError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyncCommandBufferBuilderError> for QueryError {
|
impl From<SyncCommandBufferBuilderError> for QueryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
||||||
Self::SyncCommandBufferBuilderError(err)
|
Self::SyncCommandBufferBuilderError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for QueryError {
|
impl From<RequirementNotMet> for QueryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -50,7 +50,6 @@ where
|
|||||||
///
|
///
|
||||||
/// `contents` specifies what kinds of commands will be recorded in the render pass, either
|
/// `contents` specifies what kinds of commands will be recorded in the render pass, either
|
||||||
/// draw commands or executions of secondary command buffers.
|
/// draw commands or executions of secondary command buffers.
|
||||||
#[inline]
|
|
||||||
pub fn begin_render_pass(
|
pub fn begin_render_pass(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut render_pass_begin_info: RenderPassBeginInfo,
|
mut render_pass_begin_info: RenderPassBeginInfo,
|
||||||
@ -59,14 +58,14 @@ where
|
|||||||
self.validate_begin_render_pass(&mut render_pass_begin_info, contents)?;
|
self.validate_begin_render_pass(&mut render_pass_begin_info, contents)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let &RenderPassBeginInfo {
|
let RenderPassBeginInfo {
|
||||||
ref render_pass,
|
ref render_pass,
|
||||||
ref framebuffer,
|
ref framebuffer,
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
render_area_extent,
|
render_area_extent,
|
||||||
clear_values: _,
|
clear_values: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = &render_pass_begin_info;
|
} = render_pass_begin_info;
|
||||||
|
|
||||||
let subpass = render_pass.clone().first_subpass();
|
let subpass = render_pass.clone().first_subpass();
|
||||||
let view_mask = subpass.subpass_desc().view_mask;
|
let view_mask = subpass.subpass_desc().view_mask;
|
||||||
@ -85,8 +84,8 @@ where
|
|||||||
|
|
||||||
self.inner
|
self.inner
|
||||||
.begin_render_pass(render_pass_begin_info, contents)?;
|
.begin_render_pass(render_pass_begin_info, contents)?;
|
||||||
|
|
||||||
self.render_pass_state = Some(render_pass_state);
|
self.render_pass_state = Some(render_pass_state);
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,12 +112,12 @@ where
|
|||||||
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
return Err(RenderPassError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
let &mut RenderPassBeginInfo {
|
let RenderPassBeginInfo {
|
||||||
ref render_pass,
|
render_pass,
|
||||||
ref framebuffer,
|
framebuffer,
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
render_area_extent,
|
render_area_extent,
|
||||||
ref clear_values,
|
clear_values,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = render_pass_begin_info;
|
} = render_pass_begin_info;
|
||||||
|
|
||||||
@ -208,12 +207,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
for subpass_desc in render_pass.subpasses() {
|
for subpass_desc in render_pass.subpasses() {
|
||||||
let &SubpassDescription {
|
let SubpassDescription {
|
||||||
view_mask: _,
|
view_mask: _,
|
||||||
ref input_attachments,
|
input_attachments,
|
||||||
ref color_attachments,
|
color_attachments,
|
||||||
ref resolve_attachments,
|
resolve_attachments,
|
||||||
ref depth_stencil_attachment,
|
depth_stencil_attachment,
|
||||||
preserve_attachments: _,
|
preserve_attachments: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = subpass_desc;
|
} = subpass_desc;
|
||||||
@ -288,7 +287,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-VkRenderPassBeginInfo-clearValueCount-04962
|
// 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()
|
.attachments()
|
||||||
.iter()
|
.iter()
|
||||||
.zip(clear_values)
|
.zip(clear_values)
|
||||||
@ -396,7 +395,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Advances to the next subpass of the render pass previously begun with `begin_render_pass`.
|
/// Advances to the next subpass of the render pass previously begun with `begin_render_pass`.
|
||||||
#[inline]
|
|
||||||
pub fn next_subpass(
|
pub fn next_subpass(
|
||||||
&mut self,
|
&mut self,
|
||||||
contents: SubpassContents,
|
contents: SubpassContents,
|
||||||
@ -472,7 +470,6 @@ where
|
|||||||
/// Ends the render pass previously begun with `begin_render_pass`.
|
/// Ends the render pass previously begun with `begin_render_pass`.
|
||||||
///
|
///
|
||||||
/// This must be called after you went through all the subpasses.
|
/// This must be called after you went through all the subpasses.
|
||||||
#[inline]
|
|
||||||
pub fn end_render_pass(&mut self) -> Result<&mut Self, RenderPassError> {
|
pub fn end_render_pass(&mut self) -> Result<&mut Self, RenderPassError> {
|
||||||
self.validate_end_render_pass()?;
|
self.validate_end_render_pass()?;
|
||||||
|
|
||||||
@ -538,7 +535,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
mut rendering_info: RenderingInfo,
|
mut rendering_info: RenderingInfo,
|
||||||
) -> Result<&mut Self, RenderPassError> {
|
) -> Result<&mut Self, RenderPassError> {
|
||||||
{
|
{
|
||||||
let &mut RenderingInfo {
|
let RenderingInfo {
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
ref mut render_area_extent,
|
ref mut render_area_extent,
|
||||||
ref mut layer_count,
|
ref mut layer_count,
|
||||||
@ -548,7 +545,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
ref stencil_attachment,
|
ref stencil_attachment,
|
||||||
contents: _,
|
contents: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = &mut rendering_info;
|
} = rendering_info;
|
||||||
|
|
||||||
let auto_extent = render_area_extent[0] == 0 || render_area_extent[1] == 0;
|
let auto_extent = render_area_extent[0] == 0 || render_area_extent[1] == 0;
|
||||||
let auto_layers = *layer_count == 0;
|
let auto_layers = *layer_count == 0;
|
||||||
@ -622,7 +619,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
self.validate_begin_rendering(&mut rendering_info)?;
|
self.validate_begin_rendering(&mut rendering_info)?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let &RenderingInfo {
|
let RenderingInfo {
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
render_area_extent,
|
render_area_extent,
|
||||||
layer_count: _,
|
layer_count: _,
|
||||||
@ -632,7 +629,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
ref stencil_attachment,
|
ref stencil_attachment,
|
||||||
contents,
|
contents,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = &rendering_info;
|
} = rendering_info;
|
||||||
|
|
||||||
let render_pass_state = RenderPassState {
|
let render_pass_state = RenderPassState {
|
||||||
contents,
|
contents,
|
||||||
@ -765,10 +762,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
})
|
})
|
||||||
{
|
{
|
||||||
let attachment_index = attachment_index as u32;
|
let attachment_index = attachment_index as u32;
|
||||||
let &RenderingAttachmentInfo {
|
let RenderingAttachmentInfo {
|
||||||
ref image_view,
|
image_view,
|
||||||
image_layout,
|
image_layout,
|
||||||
ref resolve_info,
|
resolve_info,
|
||||||
load_op,
|
load_op,
|
||||||
store_op,
|
store_op,
|
||||||
clear_value: _,
|
clear_value: _,
|
||||||
@ -920,10 +917,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(attachment_info) = depth_attachment {
|
if let Some(attachment_info) = depth_attachment {
|
||||||
let &RenderingAttachmentInfo {
|
let RenderingAttachmentInfo {
|
||||||
ref image_view,
|
image_view,
|
||||||
image_layout,
|
image_layout,
|
||||||
ref resolve_info,
|
resolve_info,
|
||||||
load_op,
|
load_op,
|
||||||
store_op,
|
store_op,
|
||||||
clear_value: _,
|
clear_value: _,
|
||||||
@ -1047,10 +1044,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(attachment_info) = stencil_attachment {
|
if let Some(attachment_info) = stencil_attachment {
|
||||||
let &RenderingAttachmentInfo {
|
let RenderingAttachmentInfo {
|
||||||
ref image_view,
|
image_view,
|
||||||
image_layout,
|
image_layout,
|
||||||
ref resolve_info,
|
resolve_info,
|
||||||
load_op,
|
load_op,
|
||||||
store_op,
|
store_op,
|
||||||
clear_value: _,
|
clear_value: _,
|
||||||
@ -1537,9 +1534,9 @@ impl SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let &RenderPassBeginInfo {
|
let RenderPassBeginInfo {
|
||||||
ref render_pass,
|
render_pass,
|
||||||
ref framebuffer,
|
framebuffer,
|
||||||
render_area_offset: _,
|
render_area_offset: _,
|
||||||
render_area_extent: _,
|
render_area_extent: _,
|
||||||
clear_values: _,
|
clear_values: _,
|
||||||
@ -1658,14 +1655,14 @@ impl SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let &RenderingInfo {
|
let RenderingInfo {
|
||||||
render_area_offset: _,
|
render_area_offset: _,
|
||||||
render_area_extent: _,
|
render_area_extent: _,
|
||||||
layer_count: _,
|
layer_count: _,
|
||||||
view_mask: _,
|
view_mask: _,
|
||||||
ref color_attachments,
|
color_attachments,
|
||||||
ref depth_attachment,
|
depth_attachment,
|
||||||
ref stencil_attachment,
|
stencil_attachment,
|
||||||
contents: _,
|
contents: _,
|
||||||
_ne,
|
_ne,
|
||||||
} = &rendering_info;
|
} = &rendering_info;
|
||||||
@ -2076,6 +2073,7 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdBeginRendering` on the builder.
|
/// Calls `vkCmdBeginRendering` on the builder.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn begin_rendering(&mut self, rendering_info: &RenderingInfo) {
|
pub unsafe fn begin_rendering(&mut self, rendering_info: &RenderingInfo) {
|
||||||
let &RenderingInfo {
|
let &RenderingInfo {
|
||||||
render_area_offset,
|
render_area_offset,
|
||||||
@ -2178,6 +2176,7 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdEndRendering` on the builder.
|
/// Calls `vkCmdEndRendering` on the builder.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn end_rendering(&mut self) {
|
pub unsafe fn end_rendering(&mut self) {
|
||||||
let fns = self.device.fns();
|
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
|
/// 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.
|
/// no-op and isn't a valid usage of the command anyway.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn clear_attachments(
|
pub unsafe fn clear_attachments(
|
||||||
&mut self,
|
&mut self,
|
||||||
attachments: impl IntoIterator<Item = ClearAttachment>,
|
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)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum ClearAttachment {
|
pub enum ClearAttachment {
|
||||||
/// Clear the color attachment at the specified index, with the specified clear value.
|
/// 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 {
|
impl From<ClearAttachment> for ash::vk::ClearAttachment {
|
||||||
|
#[inline]
|
||||||
fn from(v: ClearAttachment) -> Self {
|
fn from(v: ClearAttachment) -> Self {
|
||||||
match v {
|
match v {
|
||||||
ClearAttachment::Color {
|
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)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct ClearRect {
|
pub struct ClearRect {
|
||||||
/// The rectangle offset.
|
/// The rectangle offset.
|
||||||
@ -2656,7 +2659,8 @@ pub enum RenderPassError {
|
|||||||
attachment_index: u32,
|
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,
|
ContentsForbiddenInSecondaryCommandBuffer,
|
||||||
|
|
||||||
/// The depth attachment has a format that does not support that usage.
|
/// The depth attachment has a format that does not support that usage.
|
||||||
@ -2816,7 +2820,6 @@ pub enum RenderPassError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for RenderPassError {
|
impl Error for RenderPassError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
||||||
@ -2826,11 +2829,9 @@ impl Error for RenderPassError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for RenderPassError {
|
impl Display for RenderPassError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -2839,32 +2840,35 @@ impl Display for RenderPassError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::AttachmentImageMissingUsage {
|
||||||
Self::AttachmentImageMissingUsage { attachment_index, usage } => write!(
|
attachment_index,
|
||||||
|
usage,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment_index, usage,
|
||||||
),
|
),
|
||||||
Self::AutoExtentAttachmentsEmpty => write!(
|
Self::AutoExtentAttachmentsEmpty => write!(
|
||||||
f,
|
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!(
|
Self::AutoLayersAttachmentsEmpty => write!(
|
||||||
f,
|
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 {
|
Self::ClearAttachmentNotCompatible {
|
||||||
clear_attachment,
|
clear_attachment,
|
||||||
attachment_format,
|
attachment_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"a clear attachment value ({:?}) is not compatible with the attachment's format ({:?})",
|
"a clear attachment value ({:?}) is not compatible with the attachment's format \
|
||||||
clear_attachment,
|
({:?})",
|
||||||
attachment_format,
|
clear_attachment, attachment_format,
|
||||||
),
|
),
|
||||||
Self::ClearValueMissing {
|
Self::ClearValueMissing { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"a clear value for render pass attachment {} is missing",
|
"a clear value for render pass attachment {} is missing",
|
||||||
attachment_index,
|
attachment_index,
|
||||||
@ -2875,7 +2879,8 @@ impl Display for RenderPassError {
|
|||||||
attachment_format,
|
attachment_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
clear_value, attachment_index, attachment_format,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentIndexOutOfRange {
|
Self::ColorAttachmentIndexOutOfRange {
|
||||||
@ -2883,84 +2888,74 @@ impl Display for RenderPassError {
|
|||||||
num_color_attachments,
|
num_color_attachments,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
color_attachment_index, num_color_attachments,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentLayoutInvalid {
|
Self::ColorAttachmentLayoutInvalid { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"color attachment {} has a layout that is not supported",
|
"color attachment {} has a layout that is not supported",
|
||||||
attachment_index,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentMissingUsage {
|
Self::ColorAttachmentMissingUsage { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"color attachment {} is missing the `color_attachment` usage",
|
"color attachment {} is missing the `color_attachment` usage",
|
||||||
attachment_index,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentResolveFormatMismatch {
|
Self::ColorAttachmentResolveFormatMismatch { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentResolveLayoutInvalid {
|
Self::ColorAttachmentResolveLayoutInvalid { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"color resolve attachment {} has a layout that is not supported",
|
"color resolve attachment {} has a layout that is not supported",
|
||||||
attachment_index,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentResolveModeNotSupported {
|
Self::ColorAttachmentResolveModeNotSupported { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"color resolve attachment {} has a resolve mode that is not supported",
|
"color resolve attachment {} has a resolve mode that is not supported",
|
||||||
attachment_index,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentResolveMultisampled {
|
Self::ColorAttachmentResolveMultisampled { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentSamplesMismatch {
|
Self::ColorAttachmentSamplesMismatch { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ColorAttachmentWithResolveNotMultisampled {
|
Self::ColorAttachmentWithResolveNotMultisampled { attachment_index } => write!(
|
||||||
attachment_index,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
attachment_index,
|
||||||
),
|
),
|
||||||
Self::ContentsForbiddenInSecondaryCommandBuffer => write!(
|
Self::ContentsForbiddenInSecondaryCommandBuffer => write!(
|
||||||
f,
|
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!(
|
Self::DepthAttachmentFormatUsageNotSupported => write!(
|
||||||
f,
|
f,
|
||||||
"the depth attachment has a format that does not support that usage",
|
"the depth attachment has a format that does not support that usage",
|
||||||
),
|
),
|
||||||
Self::DepthAttachmentLayoutInvalid => write!(
|
Self::DepthAttachmentLayoutInvalid => {
|
||||||
f,
|
write!(f, "the depth attachment has a layout that is not supported")
|
||||||
"the depth attachment has a layout that is not supported",
|
}
|
||||||
),
|
|
||||||
Self::DepthAttachmentMissingUsage => write!(
|
Self::DepthAttachmentMissingUsage => write!(
|
||||||
f,
|
f,
|
||||||
"the depth attachment is missing the `depth_stencil_attachment` usage",
|
"the depth attachment is missing the `depth_stencil_attachment` usage",
|
||||||
),
|
),
|
||||||
Self::DepthAttachmentResolveFormatMismatch => write!(
|
Self::DepthAttachmentResolveFormatMismatch => write!(
|
||||||
f,
|
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!(
|
Self::DepthAttachmentResolveLayoutInvalid => write!(
|
||||||
f,
|
f,
|
||||||
@ -2972,15 +2967,18 @@ impl Display for RenderPassError {
|
|||||||
),
|
),
|
||||||
Self::DepthAttachmentResolveMultisampled => write!(
|
Self::DepthAttachmentResolveMultisampled => write!(
|
||||||
f,
|
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!(
|
Self::DepthAttachmentSamplesMismatch => write!(
|
||||||
f,
|
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!(
|
Self::DepthAttachmentWithResolveNotMultisampled => write!(
|
||||||
f,
|
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!(
|
Self::DepthStencilAttachmentImageViewMismatch => write!(
|
||||||
f,
|
f,
|
||||||
@ -3002,45 +3000,49 @@ impl Display for RenderPassError {
|
|||||||
}
|
}
|
||||||
Self::ForbiddenWithBeginRendering => write!(
|
Self::ForbiddenWithBeginRendering => write!(
|
||||||
f,
|
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!(
|
Self::ForbiddenWithBeginRenderPass => write!(
|
||||||
f,
|
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!(
|
Self::ForbiddenWithInheritedRenderPass => write!(
|
||||||
f,
|
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,
|
f,
|
||||||
"operation forbidden inside a render subpass with contents {:?}",
|
"operation forbidden inside a render subpass with contents {:?}",
|
||||||
subpass_contents,
|
subpass_contents,
|
||||||
),
|
),
|
||||||
Self::FramebufferNotCompatible => write!(
|
Self::FramebufferNotCompatible => {
|
||||||
f,
|
write!(f, "the framebuffer is not compatible with the render pass")
|
||||||
"the framebuffer is not compatible with the render pass",
|
}
|
||||||
),
|
|
||||||
Self::MaxColorAttachmentsExceeded { .. } => {
|
Self::MaxColorAttachmentsExceeded { .. } => {
|
||||||
write!(f, "the `max_color_attachments` limit has been exceeded",)
|
write!(f, "the `max_color_attachments` limit has been exceeded")
|
||||||
}
|
}
|
||||||
Self::MaxMultiviewViewCountExceeded { .. } => {
|
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!(
|
Self::MultiviewLayersInvalid => write!(
|
||||||
f,
|
f,
|
||||||
"the render pass uses multiview, but `layer_count` was not 0 or 1",
|
"the render pass uses multiview, but `layer_count` was not 0 or 1",
|
||||||
),
|
),
|
||||||
Self::MultiviewRectArrayLayersInvalid { rect_index } => write!(
|
Self::MultiviewRectArrayLayersInvalid { rect_index } => write!(
|
||||||
f,
|
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,
|
rect_index,
|
||||||
),
|
),
|
||||||
Self::NoSubpassesRemaining {
|
Self::NoSubpassesRemaining { current_subpass } => write!(
|
||||||
current_subpass,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
current_subpass,
|
||||||
),
|
),
|
||||||
Self::NotSupportedByQueueFamily => {
|
Self::NotSupportedByQueueFamily => {
|
||||||
@ -3048,7 +3050,7 @@ impl Display for RenderPassError {
|
|||||||
}
|
}
|
||||||
Self::QueryIsActive => write!(
|
Self::QueryIsActive => write!(
|
||||||
f,
|
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!(
|
Self::RectArrayLayersEmpty { rect_index } => write!(
|
||||||
f,
|
f,
|
||||||
@ -3057,17 +3059,17 @@ impl Display for RenderPassError {
|
|||||||
),
|
),
|
||||||
Self::RectArrayLayersOutOfBounds { rect_index } => write!(
|
Self::RectArrayLayersOutOfBounds { rect_index } => write!(
|
||||||
f,
|
f,
|
||||||
"clear rectangle index {} `array_layers` is outside the range of layers of the attachments",
|
"clear rectangle index {} `array_layers` is outside the range of layers of the \
|
||||||
rect_index,
|
attachments",
|
||||||
),
|
|
||||||
Self::RectExtentZero { rect_index } => write!(
|
|
||||||
f,
|
|
||||||
"clear rectangle index {} `extent` is zero",
|
|
||||||
rect_index,
|
rect_index,
|
||||||
),
|
),
|
||||||
|
Self::RectExtentZero { rect_index } => {
|
||||||
|
write!(f, "clear rectangle index {} `extent` is zero", rect_index)
|
||||||
|
}
|
||||||
Self::RectOutOfBounds { rect_index } => write!(
|
Self::RectOutOfBounds { rect_index } => write!(
|
||||||
f,
|
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,
|
rect_index,
|
||||||
),
|
),
|
||||||
Self::RenderAreaOutOfBounds => write!(
|
Self::RenderAreaOutOfBounds => write!(
|
||||||
@ -3088,7 +3090,8 @@ impl Display for RenderPassError {
|
|||||||
),
|
),
|
||||||
Self::StencilAttachmentResolveFormatMismatch => write!(
|
Self::StencilAttachmentResolveFormatMismatch => write!(
|
||||||
f,
|
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!(
|
Self::StencilAttachmentResolveLayoutInvalid => write!(
|
||||||
f,
|
f,
|
||||||
@ -3100,22 +3103,26 @@ impl Display for RenderPassError {
|
|||||||
),
|
),
|
||||||
Self::StencilAttachmentResolveMultisampled => write!(
|
Self::StencilAttachmentResolveMultisampled => write!(
|
||||||
f,
|
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!(
|
Self::StencilAttachmentSamplesMismatch => write!(
|
||||||
f,
|
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!(
|
Self::StencilAttachmentWithResolveNotMultisampled => write!(
|
||||||
f,
|
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 {
|
Self::SubpassesRemaining {
|
||||||
current_subpass,
|
current_subpass,
|
||||||
remaining_subpasses,
|
remaining_subpasses,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
current_subpass, remaining_subpasses,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -3123,14 +3130,12 @@ impl Display for RenderPassError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyncCommandBufferBuilderError> for RenderPassError {
|
impl From<SyncCommandBufferBuilderError> for RenderPassError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
||||||
Self::SyncCommandBufferBuilderError(err)
|
Self::SyncCommandBufferBuilderError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for RenderPassError {
|
impl From<RequirementNotMet> for RenderPassError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -59,7 +59,8 @@ where
|
|||||||
// Secondary command buffer could leave the primary in any state.
|
// Secondary command buffer could leave the primary in any state.
|
||||||
self.inner.reset_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);
|
self.usage = std::cmp::min(self.usage, secondary_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +97,8 @@ where
|
|||||||
// Secondary command buffer could leave the primary in any state.
|
// Secondary command buffer could leave the primary in any state.
|
||||||
self.inner.reset_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);
|
self.usage = std::cmp::min(self.usage, secondary_usage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +413,6 @@ pub struct SyncCommandBufferBuilderExecuteCommands<'a> {
|
|||||||
|
|
||||||
impl<'a> SyncCommandBufferBuilderExecuteCommands<'a> {
|
impl<'a> SyncCommandBufferBuilderExecuteCommands<'a> {
|
||||||
/// Adds a command buffer to the list.
|
/// Adds a command buffer to the list.
|
||||||
#[inline]
|
|
||||||
pub fn add(&mut self, command_buffer: impl SecondaryCommandBuffer + 'static) {
|
pub fn add(&mut self, command_buffer: impl SecondaryCommandBuffer + 'static) {
|
||||||
self.inner.push(Box::new(command_buffer));
|
self.inner.push(Box::new(command_buffer));
|
||||||
}
|
}
|
||||||
@ -541,7 +542,6 @@ impl UnsafeCommandBufferBuilderExecuteCommands {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a command buffer to the list.
|
/// Adds a command buffer to the list.
|
||||||
#[inline]
|
|
||||||
pub fn add(&mut self, cb: &(impl SecondaryCommandBuffer + ?Sized)) {
|
pub fn add(&mut self, cb: &(impl SecondaryCommandBuffer + ?Sized)) {
|
||||||
// TODO: debug assert that it is a secondary command buffer?
|
// TODO: debug assert that it is a secondary command buffer?
|
||||||
self.raw_cbs.push(cb.inner().internal_object());
|
self.raw_cbs.push(cb.inner().internal_object());
|
||||||
@ -694,7 +694,6 @@ pub enum ExecuteCommandsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ExecuteCommandsError {
|
impl Error for ExecuteCommandsError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
Self::SyncCommandBufferBuilderError(err) => Some(err),
|
||||||
@ -704,11 +703,9 @@ impl Error for ExecuteCommandsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ExecuteCommandsError {
|
impl Display for ExecuteCommandsError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
Self::SyncCommandBufferBuilderError(_) => write!(f, "a SyncCommandBufferBuilderError"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -717,8 +714,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::ForbiddenWithSubpassContents {
|
||||||
Self::ForbiddenWithSubpassContents { contents: subpass_contents } => write!(
|
contents: subpass_contents,
|
||||||
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"operation forbidden inside a render subpass with contents {:?}",
|
"operation forbidden inside a render subpass with contents {:?}",
|
||||||
subpass_contents,
|
subpass_contents,
|
||||||
@ -730,7 +728,8 @@ impl Display for ExecuteCommandsError {
|
|||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
command_buffer_index,
|
||||||
),
|
),
|
||||||
Self::OcclusionQueryFlagsNotSuperset {
|
Self::OcclusionQueryFlagsNotSuperset {
|
||||||
@ -739,7 +738,8 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_flags,
|
inherited_flags,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
inherited_flags, command_buffer_index, required_flags,
|
||||||
),
|
),
|
||||||
Self::PipelineStatisticsQueryFlagsNotSuperset {
|
Self::PipelineStatisticsQueryFlagsNotSuperset {
|
||||||
@ -748,7 +748,8 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_flags,
|
inherited_flags,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
inherited_flags, command_buffer_index, required_flags,
|
||||||
),
|
),
|
||||||
Self::RenderPassColorAttachmentCountMismatch {
|
Self::RenderPassColorAttachmentCountMismatch {
|
||||||
@ -757,10 +758,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_count,
|
inherited_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited color attachment count ({}) of command buffer {} does not match the current attachment count ({})",
|
"the inherited color attachment count ({}) of command buffer {} does not match the \
|
||||||
inherited_count,
|
current attachment count ({})",
|
||||||
command_buffer_index,
|
inherited_count, command_buffer_index, required_count,
|
||||||
required_count,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassColorAttachmentFormatMismatch {
|
Self::RenderPassColorAttachmentFormatMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -769,11 +769,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_format,
|
inherited_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited format ({:?}) of color attachment {} of command buffer {} does not match the current attachment format ({:?})",
|
"the inherited format ({:?}) of color attachment {} of command buffer {} does not \
|
||||||
inherited_format,
|
match the current attachment format ({:?})",
|
||||||
color_attachment_index,
|
inherited_format, color_attachment_index, command_buffer_index, required_format,
|
||||||
command_buffer_index,
|
|
||||||
required_format,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassColorAttachmentSamplesMismatch {
|
Self::RenderPassColorAttachmentSamplesMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -782,11 +780,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_samples,
|
inherited_samples,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited sample count ({:?}) of color attachment {} of command buffer {} does not match the current attachment sample count ({:?})",
|
"the inherited sample count ({:?}) of color attachment {} of command buffer {} \
|
||||||
inherited_samples,
|
does not match the current attachment sample count ({:?})",
|
||||||
color_attachment_index,
|
inherited_samples, color_attachment_index, command_buffer_index, required_samples,
|
||||||
command_buffer_index,
|
|
||||||
required_samples,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassDepthAttachmentFormatMismatch {
|
Self::RenderPassDepthAttachmentFormatMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -794,10 +790,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_format,
|
inherited_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited format ({:?}) of the depth attachment of command buffer {} does not match the current attachment format ({:?})",
|
"the inherited format ({:?}) of the depth attachment of command buffer {} does not \
|
||||||
inherited_format,
|
match the current attachment format ({:?})",
|
||||||
command_buffer_index,
|
inherited_format, command_buffer_index, required_format,
|
||||||
required_format,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassDepthAttachmentSamplesMismatch {
|
Self::RenderPassDepthAttachmentSamplesMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -805,37 +800,40 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_samples,
|
inherited_samples,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited sample count ({:?}) of the depth attachment of command buffer {} does not match the current attachment sample count ({:?})",
|
"the inherited sample count ({:?}) of the depth attachment of command buffer {} \
|
||||||
inherited_samples,
|
does not match the current attachment sample count ({:?})",
|
||||||
command_buffer_index,
|
inherited_samples, command_buffer_index, required_samples,
|
||||||
required_samples,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassFramebufferMismatch {
|
Self::RenderPassFramebufferMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
command_buffer_index,
|
||||||
),
|
),
|
||||||
Self::RenderPassInheritanceRequired {
|
Self::RenderPassInheritanceRequired {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
command_buffer_index,
|
||||||
),
|
),
|
||||||
Self::RenderPassInheritanceForbidden {
|
Self::RenderPassInheritanceForbidden {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
command_buffer_index,
|
||||||
),
|
),
|
||||||
Self::RenderPassNotCompatible {
|
Self::RenderPassNotCompatible {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
command_buffer_index,
|
||||||
),
|
),
|
||||||
Self::RenderPassStencilAttachmentFormatMismatch {
|
Self::RenderPassStencilAttachmentFormatMismatch {
|
||||||
@ -844,10 +842,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_format,
|
inherited_format,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited format ({:?}) of the stencil attachment of command buffer {} does not match the current attachment format ({:?})",
|
"the inherited format ({:?}) of the stencil attachment of command buffer {} does \
|
||||||
inherited_format,
|
not match the current attachment format ({:?})",
|
||||||
command_buffer_index,
|
inherited_format, command_buffer_index, required_format,
|
||||||
required_format,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassStencilAttachmentSamplesMismatch {
|
Self::RenderPassStencilAttachmentSamplesMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -855,10 +852,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_samples,
|
inherited_samples,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited sample count ({:?}) of the stencil attachment of command buffer {} does not match the current attachment sample count ({:?})",
|
"the inherited sample count ({:?}) of the stencil attachment of command buffer {} \
|
||||||
inherited_samples,
|
does not match the current attachment sample count ({:?})",
|
||||||
command_buffer_index,
|
inherited_samples, command_buffer_index, required_samples,
|
||||||
required_samples,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassSubpassMismatch {
|
Self::RenderPassSubpassMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -866,10 +862,9 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_subpass,
|
inherited_subpass,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited subpass index ({}) of command buffer {} does not match the current subpass index ({})",
|
"the inherited subpass index ({}) of command buffer {} does not match the current \
|
||||||
inherited_subpass,
|
subpass index ({})",
|
||||||
command_buffer_index,
|
inherited_subpass, command_buffer_index, required_subpass,
|
||||||
required_subpass,
|
|
||||||
),
|
),
|
||||||
Self::RenderPassTypeMismatch {
|
Self::RenderPassTypeMismatch {
|
||||||
command_buffer_index,
|
command_buffer_index,
|
||||||
@ -884,17 +879,15 @@ impl Display for ExecuteCommandsError {
|
|||||||
inherited_view_mask,
|
inherited_view_mask,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the inherited view mask ({}) of command buffer {} does not match the current view mask ({})",
|
"the inherited view mask ({}) of command buffer {} does not match the current view \
|
||||||
inherited_view_mask,
|
mask ({})",
|
||||||
command_buffer_index,
|
inherited_view_mask, command_buffer_index, required_view_mask,
|
||||||
required_view_mask,
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyncCommandBufferBuilderError> for ExecuteCommandsError {
|
impl From<SyncCommandBufferBuilderError> for ExecuteCommandsError {
|
||||||
#[inline]
|
|
||||||
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
fn from(err: SyncCommandBufferBuilderError) -> Self {
|
||||||
Self::SyncCommandBufferBuilderError(err)
|
Self::SyncCommandBufferBuilderError(err)
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
///
|
///
|
||||||
/// - Panics if `src_buffer` or `dst_buffer` were not created from the same device
|
/// - Panics if `src_buffer` or `dst_buffer` were not created from the same device
|
||||||
/// as `self`.
|
/// as `self`.
|
||||||
#[inline]
|
|
||||||
pub fn copy_buffer(
|
pub fn copy_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
copy_buffer_info: impl Into<CopyBufferInfo>,
|
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
|
/// - Panics if `src_image` or `dst_image` were not created from the same device
|
||||||
/// as `self`.
|
/// as `self`.
|
||||||
#[inline]
|
|
||||||
pub fn copy_image(&mut self, copy_image_info: CopyImageInfo) -> Result<&mut Self, CopyError> {
|
pub fn copy_image(&mut self, copy_image_info: CopyImageInfo) -> Result<&mut Self, CopyError> {
|
||||||
self.validate_copy_image(©_image_info)?;
|
self.validate_copy_image(©_image_info)?;
|
||||||
|
|
||||||
@ -872,7 +870,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Copies from a buffer to an image.
|
/// Copies from a buffer to an image.
|
||||||
#[inline]
|
|
||||||
pub fn copy_buffer_to_image(
|
pub fn copy_buffer_to_image(
|
||||||
&mut self,
|
&mut self,
|
||||||
copy_buffer_to_image_info: CopyBufferToImageInfo,
|
copy_buffer_to_image_info: CopyBufferToImageInfo,
|
||||||
@ -1304,7 +1301,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Copies from an image to a buffer.
|
/// Copies from an image to a buffer.
|
||||||
#[inline]
|
|
||||||
pub fn copy_image_to_buffer(
|
pub fn copy_image_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
copy_image_to_buffer_info: CopyImageToBufferInfo,
|
copy_image_to_buffer_info: CopyImageToBufferInfo,
|
||||||
@ -1736,7 +1732,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `dst_buffer` was not created from the same device as `self`.
|
/// - Panics if `dst_buffer` was not created from the same device as `self`.
|
||||||
#[inline]
|
|
||||||
pub fn fill_buffer(
|
pub fn fill_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
fill_buffer_info: FillBufferInfo,
|
fill_buffer_info: FillBufferInfo,
|
||||||
@ -1840,7 +1835,6 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `dst_buffer` was not created from the same device as `self`.
|
/// - Panics if `dst_buffer` was not created from the same device as `self`.
|
||||||
#[inline]
|
|
||||||
pub fn update_buffer<B, D, Dd>(
|
pub fn update_buffer<B, D, Dd>(
|
||||||
&mut self,
|
&mut self,
|
||||||
data: Dd,
|
data: Dd,
|
||||||
@ -2410,7 +2404,6 @@ impl SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdUpdateBuffer` on the builder.
|
/// Calls `vkCmdUpdateBuffer` on the builder.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn update_buffer<D, Dd>(
|
pub unsafe fn update_buffer<D, Dd>(
|
||||||
&mut self,
|
&mut self,
|
||||||
data: Dd,
|
data: Dd,
|
||||||
@ -2998,7 +2991,6 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Calls `vkCmdUpdateBuffer` on the builder.
|
/// Calls `vkCmdUpdateBuffer` on the builder.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn update_buffer<D>(
|
pub unsafe fn update_buffer<D>(
|
||||||
&mut self,
|
&mut self,
|
||||||
data: &D,
|
data: &D,
|
||||||
@ -3098,7 +3090,6 @@ where
|
|||||||
D: TypedBufferAccess<Content = [T]>,
|
D: TypedBufferAccess<Content = [T]>,
|
||||||
{
|
{
|
||||||
/// Returns a `CopyBufferInfoTyped` with the specified `src_buffer` and `dst_buffer`.
|
/// Returns a `CopyBufferInfoTyped` with the specified `src_buffer` and `dst_buffer`.
|
||||||
#[inline]
|
|
||||||
pub fn buffers(src_buffer: Arc<S>, dst_buffer: Arc<D>) -> Self {
|
pub fn buffers(src_buffer: Arc<S>, dst_buffer: Arc<D>) -> Self {
|
||||||
let region = BufferCopy {
|
let region = BufferCopy {
|
||||||
size: min(src_buffer.len(), dst_buffer.len()),
|
size: min(src_buffer.len(), dst_buffer.len()),
|
||||||
@ -3119,7 +3110,6 @@ where
|
|||||||
S: TypedBufferAccess<Content = [T]> + 'static,
|
S: TypedBufferAccess<Content = [T]> + 'static,
|
||||||
D: TypedBufferAccess<Content = [T]> + 'static,
|
D: TypedBufferAccess<Content = [T]> + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn from(typed: CopyBufferInfoTyped<S, D, T>) -> Self {
|
fn from(typed: CopyBufferInfoTyped<S, D, T>) -> Self {
|
||||||
let CopyBufferInfoTyped {
|
let CopyBufferInfoTyped {
|
||||||
src_buffer,
|
src_buffer,
|
||||||
|
@ -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.
|
/// 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
|
/// If the implementation frees or resets the command buffer, it must not forget that this
|
||||||
/// operation must lock the pool.
|
/// operation must lock the pool.
|
||||||
///
|
|
||||||
pub unsafe trait CommandPool: DeviceOwned {
|
pub unsafe trait CommandPool: DeviceOwned {
|
||||||
/// See `alloc()`.
|
/// See `alloc()`.
|
||||||
type Iter: Iterator<Item = Self::Builder>;
|
type Iter: Iterator<Item = Self::Builder>;
|
||||||
|
|
||||||
/// Represents a command buffer that has been allocated and that is currently being built.
|
/// Represents a command buffer that has been allocated and that is currently being built.
|
||||||
type Builder: CommandPoolBuilderAlloc<Alloc = Self::Alloc>;
|
type Builder: CommandPoolBuilderAlloc<Alloc = Self::Alloc>;
|
||||||
|
|
||||||
/// Represents a command buffer that has been allocated and that is pending execution or is
|
/// Represents a command buffer that has been allocated and that is pending execution or is
|
||||||
/// being executed.
|
/// being executed.
|
||||||
type Alloc: CommandPoolAlloc;
|
type Alloc: CommandPoolAlloc;
|
||||||
@ -76,7 +77,6 @@ pub unsafe trait CommandPool: DeviceOwned {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// See `CommandPool` for information about safety.
|
/// See `CommandPool` for information about safety.
|
||||||
///
|
|
||||||
pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
|
pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
|
||||||
/// Return type of `into_alloc`.
|
/// Return type of `into_alloc`.
|
||||||
type Alloc: CommandPoolAlloc;
|
type Alloc: CommandPoolAlloc;
|
||||||
@ -96,7 +96,6 @@ pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// See `CommandPool` for information about safety.
|
/// See `CommandPool` for information about safety.
|
||||||
///
|
|
||||||
pub unsafe trait CommandPoolAlloc: DeviceOwned + Send + Sync {
|
pub unsafe trait CommandPoolAlloc: DeviceOwned + Send + Sync {
|
||||||
/// Returns the internal object that contains the command buffer.
|
/// Returns the internal object that contains the command buffer.
|
||||||
fn inner(&self) -> &UnsafeCommandPoolAlloc;
|
fn inner(&self) -> &UnsafeCommandPoolAlloc;
|
||||||
|
@ -77,6 +77,7 @@ unsafe impl CommandPool for Arc<StandardCommandPool> {
|
|||||||
type Builder = StandardCommandPoolBuilder;
|
type Builder = StandardCommandPoolBuilder;
|
||||||
type Alloc = StandardCommandPoolAlloc;
|
type Alloc = StandardCommandPoolAlloc;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn allocate(
|
fn allocate(
|
||||||
&self,
|
&self,
|
||||||
level: CommandBufferLevel,
|
level: CommandBufferLevel,
|
||||||
@ -212,6 +213,7 @@ unsafe impl DeviceOwned for StandardCommandPoolAlloc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for StandardCommandPoolAlloc {
|
impl Drop for StandardCommandPoolAlloc {
|
||||||
|
#[inline]
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
// Safe because `self.cmd` is wrapped in a `ManuallyDrop`.
|
// Safe because `self.cmd` is wrapped in a `ManuallyDrop`.
|
||||||
let cmd: UnsafeCommandPoolAlloc = unsafe { ptr::read(&*self.cmd) };
|
let cmd: UnsafeCommandPoolAlloc = unsafe { ptr::read(&*self.cmd) };
|
||||||
|
@ -78,6 +78,7 @@ impl UnsafeCommandPool {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::CommandPool,
|
handle: ash::vk::CommandPool,
|
||||||
@ -175,6 +176,7 @@ impl UnsafeCommandPool {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - The command buffers allocated from this pool jump to the initial state.
|
/// - The command buffers allocated from this pool jump to the initial state.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn reset(&self, release_resources: bool) -> Result<(), OomError> {
|
pub unsafe fn reset(&self, release_resources: bool) -> Result<(), OomError> {
|
||||||
let flags = if release_resources {
|
let flags = if release_resources {
|
||||||
ash::vk::CommandPoolResetFlags::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)
|
(fns.v1_0.reset_command_pool)(self.device.internal_object(), self.handle, flags)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Allocates command buffers.
|
/// Allocates command buffers.
|
||||||
|
#[inline]
|
||||||
pub fn allocate_command_buffers(
|
pub fn allocate_command_buffers(
|
||||||
&self,
|
&self,
|
||||||
allocate_info: CommandBufferAllocateInfo,
|
allocate_info: CommandBufferAllocateInfo,
|
||||||
@ -269,6 +273,7 @@ impl UnsafeCommandPool {
|
|||||||
/// enabled on the device. Otherwise an error is returned.
|
/// enabled on the device. Otherwise an error is returned.
|
||||||
/// Since this operation is purely an optimization it is legitimate to call this function and
|
/// Since this operation is purely an optimization it is legitimate to call this function and
|
||||||
/// simply ignore any possible error.
|
/// simply ignore any possible error.
|
||||||
|
#[inline]
|
||||||
pub fn trim(&self) -> Result<(), CommandPoolTrimError> {
|
pub fn trim(&self) -> Result<(), CommandPoolTrimError> {
|
||||||
if !(self.device.api_version() >= Version::V1_1
|
if !(self.device.api_version() >= Version::V1_1
|
||||||
|| self.device.enabled_extensions().khr_maintenance1)
|
|| self.device.enabled_extensions().khr_maintenance1)
|
||||||
@ -351,7 +356,6 @@ impl PartialEq for UnsafeCommandPool {
|
|||||||
impl Eq for UnsafeCommandPool {}
|
impl Eq for UnsafeCommandPool {}
|
||||||
|
|
||||||
impl Hash for UnsafeCommandPool {
|
impl Hash for UnsafeCommandPool {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -373,26 +377,25 @@ pub enum UnsafeCommandPoolCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for UnsafeCommandPoolCreationError {
|
impl Error for UnsafeCommandPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for UnsafeCommandPoolCreationError {
|
impl Display for UnsafeCommandPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory",),
|
Self::OomError(_) => write!(f, "not enough memory",),
|
||||||
Self::QueueFamilyIndexOutOfRange {
|
Self::QueueFamilyIndexOutOfRange {
|
||||||
queue_family_index,
|
queue_family_index,
|
||||||
queue_family_count,
|
queue_family_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
queue_family_index, queue_family_count,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -400,7 +403,6 @@ impl Display for UnsafeCommandPoolCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for UnsafeCommandPoolCreationError {
|
impl From<VulkanError> for UnsafeCommandPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
@ -513,7 +515,6 @@ impl PartialEq for UnsafeCommandPoolAlloc {
|
|||||||
impl Eq for UnsafeCommandPoolAlloc {}
|
impl Eq for UnsafeCommandPoolAlloc {}
|
||||||
|
|
||||||
impl Hash for UnsafeCommandPoolAlloc {
|
impl Hash for UnsafeCommandPoolAlloc {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -532,7 +533,6 @@ pub enum CommandPoolTrimError {
|
|||||||
impl Error for CommandPoolTrimError {}
|
impl Error for CommandPoolTrimError {}
|
||||||
|
|
||||||
impl Display for CommandPoolTrimError {
|
impl Display for CommandPoolTrimError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -548,7 +548,6 @@ impl Display for CommandPoolTrimError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for CommandPoolTrimError {
|
impl From<VulkanError> for CommandPoolTrimError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> CommandPoolTrimError {
|
fn from(err: VulkanError) -> CommandPoolTrimError {
|
||||||
panic!("unexpected error: {:?}", err)
|
panic!("unexpected error: {:?}", err)
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,7 @@ impl SyncCommandBufferBuilder {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// See `UnsafeCommandBufferBuilder::new()`.
|
/// See `UnsafeCommandBufferBuilder::new()`.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn new(
|
pub unsafe fn new(
|
||||||
pool_alloc: &UnsafeCommandPoolAlloc,
|
pool_alloc: &UnsafeCommandPoolAlloc,
|
||||||
begin_info: CommandBufferBeginInfo,
|
begin_info: CommandBufferBeginInfo,
|
||||||
@ -131,8 +132,8 @@ impl SyncCommandBufferBuilder {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.render_pass
|
.render_pass
|
||||||
.is_some();
|
.is_some();
|
||||||
|
|
||||||
let inner = UnsafeCommandBufferBuilder::new(pool_alloc, begin_info)?;
|
let inner = UnsafeCommandBufferBuilder::new(pool_alloc, begin_info)?;
|
||||||
|
|
||||||
Ok(SyncCommandBufferBuilder::from_unsafe_cmd(
|
Ok(SyncCommandBufferBuilder::from_unsafe_cmd(
|
||||||
inner,
|
inner,
|
||||||
level,
|
level,
|
||||||
@ -346,18 +347,17 @@ impl SyncCommandBufferBuilder {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// Adds a command to be processed by the builder.
|
/// Adds a command to be processed by the builder.
|
||||||
//
|
///
|
||||||
// The `resources` argument should contain each buffer or image used by the command.
|
/// 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 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
|
/// - The index of the resource within the `resources` slice maps to the resource accessed
|
||||||
// through `Command::buffer(..)` or `Command::image(..)`.
|
/// through `Command::buffer(..)` or `Command::image(..)`.
|
||||||
// - `PipelineMemoryAccess` must match the way the resource has been used.
|
/// - `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
|
/// - `start_layout` and `end_layout` designate the image layout that the image is expected to
|
||||||
// in when the command starts, and the image layout that the image will be transitioned 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.
|
/// during the command. When it comes to buffers, you should pass `Undefined` for both.
|
||||||
#[inline]
|
|
||||||
pub(in crate::command_buffer) fn add_resource(
|
pub(in crate::command_buffer) fn add_resource(
|
||||||
&mut self,
|
&mut self,
|
||||||
resource: (Cow<'static, str>, Resource),
|
resource: (Cow<'static, str>, Resource),
|
||||||
@ -610,26 +610,30 @@ impl SyncCommandBufferBuilder {
|
|||||||
// We can't transition to `Preinitialized`,
|
// We can't transition to `Preinitialized`,
|
||||||
// so all we can do here is error out.
|
// so all we can do here is error out.
|
||||||
// TODO: put this in find_image_conflict instead?
|
// 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.
|
// Insert a layout transition.
|
||||||
|
|
||||||
// A layout transition is a write, so if we perform one, we need
|
// A layout transition is a write, so if we perform one, we
|
||||||
// exclusive access.
|
// need exclusive access.
|
||||||
state.memory.exclusive = true; // TODO: is this correct?
|
state.memory.exclusive = true; // TODO: is this correct?
|
||||||
state.exclusive_any = true;
|
state.exclusive_any = true;
|
||||||
|
|
||||||
// Note that we transition from `bottom_of_pipe`, which means that we
|
// Note that we transition from `bottom_of_pipe`, which
|
||||||
// wait for all the previous commands to be entirely finished. This is
|
// means that we wait for all the previous commands to be
|
||||||
// suboptimal, but:
|
// 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.
|
|
||||||
//
|
//
|
||||||
|
// - 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(
|
self.pending_barrier.image_memory_barriers.push(
|
||||||
ImageMemoryBarrier {
|
ImageMemoryBarrier {
|
||||||
source_stages: PipelineStages {
|
source_stages: PipelineStages {
|
||||||
@ -862,7 +866,6 @@ unsafe impl DeviceOwned for SyncCommandBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for SyncCommandBufferBuilder {
|
impl Debug for SyncCommandBufferBuilder {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
Debug::fmt(&self.inner, f)
|
Debug::fmt(&self.inner, f)
|
||||||
}
|
}
|
||||||
@ -885,7 +888,6 @@ pub enum SyncCommandBufferBuilderError {
|
|||||||
impl Error for SyncCommandBufferBuilderError {}
|
impl Error for SyncCommandBufferBuilderError {}
|
||||||
|
|
||||||
impl Display for SyncCommandBufferBuilderError {
|
impl Display for SyncCommandBufferBuilderError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
SyncCommandBufferBuilderError::Conflict { .. } => write!(f, "unsolvable conflict"),
|
SyncCommandBufferBuilderError::Conflict { .. } => write!(f, "unsolvable conflict"),
|
||||||
@ -895,7 +897,6 @@ impl Display for SyncCommandBufferBuilderError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<CommandBufferExecError> for SyncCommandBufferBuilderError {
|
impl From<CommandBufferExecError> for SyncCommandBufferBuilderError {
|
||||||
#[inline]
|
|
||||||
fn from(val: CommandBufferExecError) -> Self {
|
fn from(val: CommandBufferExecError) -> Self {
|
||||||
SyncCommandBufferBuilderError::ExecError(val)
|
SyncCommandBufferBuilderError::ExecError(val)
|
||||||
}
|
}
|
||||||
@ -1101,6 +1102,7 @@ pub enum SetOrPush {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl SetOrPush {
|
impl SetOrPush {
|
||||||
|
#[inline]
|
||||||
pub fn resources(&self) -> &DescriptorSetResources {
|
pub fn resources(&self) -> &DescriptorSetResources {
|
||||||
match self {
|
match self {
|
||||||
Self::Set(set) => set.as_ref().0.resources(),
|
Self::Set(set) => set.as_ref().0.resources(),
|
||||||
@ -1304,7 +1306,8 @@ impl<'a> CommandBufferState<'a> {
|
|||||||
self.current_state.rasterizer_discard_enable
|
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]
|
#[inline]
|
||||||
pub fn scissor(&self, num: u32) -> Option<&'a Scissor> {
|
pub fn scissor(&self, num: u32) -> Option<&'a Scissor> {
|
||||||
self.current_state.scissor.get(&num)
|
self.current_state.scissor.get(&num)
|
||||||
@ -1349,7 +1352,8 @@ impl<'a> CommandBufferState<'a> {
|
|||||||
self.current_state.stencil_write_mask
|
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]
|
#[inline]
|
||||||
pub fn viewport(&self, num: u32) -> Option<&'a Viewport> {
|
pub fn viewport(&self, num: u32) -> Option<&'a Viewport> {
|
||||||
self.current_state.viewport.get(&num)
|
self.current_state.viewport.get(&num)
|
||||||
|
@ -131,6 +131,7 @@ impl SyncCommandBuffer {
|
|||||||
/// Tries to lock the resources used by the command buffer.
|
/// Tries to lock the resources used by the command buffer.
|
||||||
///
|
///
|
||||||
/// > **Note**: You should call this in the implementation of the `CommandBuffer` trait.
|
/// > **Note**: You should call this in the implementation of the `CommandBuffer` trait.
|
||||||
|
#[inline]
|
||||||
pub fn lock_submit(
|
pub fn lock_submit(
|
||||||
&self,
|
&self,
|
||||||
future: &dyn GpuFuture,
|
future: &dyn GpuFuture,
|
||||||
@ -281,7 +282,7 @@ impl SyncCommandBuffer {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// The command buffer must have been successfully locked with `lock_submit()`.
|
/// The command buffer must have been successfully locked with `lock_submit()`.
|
||||||
///
|
#[inline]
|
||||||
pub unsafe fn unlock(&self) {
|
pub unsafe fn unlock(&self) {
|
||||||
for (buffer, range_map) in &self.buffers2 {
|
for (buffer, range_map) in &self.buffers2 {
|
||||||
let mut buffer_state = buffer.state();
|
let mut buffer_state = buffer.state();
|
||||||
|
@ -50,6 +50,7 @@ impl UnsafeCommandBufferBuilder {
|
|||||||
///
|
///
|
||||||
/// - `pool_alloc` must outlive the returned builder and its created command buffer.
|
/// - `pool_alloc` must outlive the returned builder and its created command buffer.
|
||||||
/// - `kind` must match how `pool_alloc` was created.
|
/// - `kind` must match how `pool_alloc` was created.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn new(
|
pub unsafe fn new(
|
||||||
pool_alloc: &UnsafeCommandPoolAlloc,
|
pool_alloc: &UnsafeCommandPoolAlloc,
|
||||||
begin_info: CommandBufferBeginInfo,
|
begin_info: CommandBufferBeginInfo,
|
||||||
|
@ -68,9 +68,9 @@ pub unsafe trait PrimaryCommandBuffer: DeviceOwned + Send + Sync {
|
|||||||
///
|
///
|
||||||
/// > **Note**: This is just a shortcut for `execute_after(vulkano::sync::now(), queue)`.
|
/// > **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]
|
#[inline]
|
||||||
fn execute(
|
fn execute(
|
||||||
self,
|
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
|
/// `std::mem::forget` on that object and "unlock" these resources. For more information about
|
||||||
/// this problem, search the web for "rust thread scoped leakpocalypse".
|
/// 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.
|
/// - Panics if the device of the command buffer is not the same as the device of the future.
|
||||||
#[inline]
|
|
||||||
fn execute_after<F>(
|
fn execute_after<F>(
|
||||||
self,
|
self,
|
||||||
future: F,
|
future: F,
|
||||||
@ -164,12 +163,10 @@ where
|
|||||||
T: SafeDeref + Send + Sync,
|
T: SafeDeref + Send + Sync,
|
||||||
T::Target: PrimaryCommandBuffer,
|
T::Target: PrimaryCommandBuffer,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeCommandBuffer {
|
fn inner(&self) -> &UnsafeCommandBuffer {
|
||||||
(**self).inner()
|
(**self).inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn lock_submit(
|
fn lock_submit(
|
||||||
&self,
|
&self,
|
||||||
future: &dyn GpuFuture,
|
future: &dyn GpuFuture,
|
||||||
@ -178,12 +175,10 @@ where
|
|||||||
(**self).lock_submit(future, queue)
|
(**self).lock_submit(future, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn unlock(&self) {
|
unsafe fn unlock(&self) {
|
||||||
(**self).unlock();
|
(**self).unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -194,7 +189,6 @@ where
|
|||||||
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -266,32 +260,26 @@ where
|
|||||||
T: SafeDeref + Send + Sync,
|
T: SafeDeref + Send + Sync,
|
||||||
T::Target: SecondaryCommandBuffer,
|
T::Target: SecondaryCommandBuffer,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeCommandBuffer {
|
fn inner(&self) -> &UnsafeCommandBuffer {
|
||||||
(**self).inner()
|
(**self).inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
|
fn lock_record(&self) -> Result<(), CommandBufferExecError> {
|
||||||
(**self).lock_record()
|
(**self).lock_record()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn unlock(&self) {
|
unsafe fn unlock(&self) {
|
||||||
(**self).unlock();
|
(**self).unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
|
fn inheritance_info(&self) -> &CommandBufferInheritanceInfo {
|
||||||
(**self).inheritance_info()
|
(**self).inheritance_info()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn num_buffers(&self) -> usize {
|
fn num_buffers(&self) -> usize {
|
||||||
(**self).num_buffers()
|
(**self).num_buffers()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn buffer(
|
fn buffer(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
@ -303,12 +291,10 @@ where
|
|||||||
(**self).buffer(index)
|
(**self).buffer(index)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn num_images(&self) -> usize {
|
fn num_images(&self) -> usize {
|
||||||
(**self).num_images()
|
(**self).num_images()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image(
|
fn image(
|
||||||
&self,
|
&self,
|
||||||
index: usize,
|
index: usize,
|
||||||
@ -325,6 +311,7 @@ where
|
|||||||
|
|
||||||
/// Represents a command buffer being executed by the GPU and the moment when the execution
|
/// Represents a command buffer being executed by the GPU and the moment when the execution
|
||||||
/// finishes.
|
/// finishes.
|
||||||
|
#[derive(Debug)]
|
||||||
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
#[must_use = "Dropping this object will immediately block the thread until the GPU has finished processing the submission"]
|
||||||
pub struct CommandBufferExecFuture<F>
|
pub struct CommandBufferExecFuture<F>
|
||||||
where
|
where
|
||||||
@ -399,7 +386,6 @@ unsafe impl<F> GpuFuture for CommandBufferExecFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.previous.cleanup_finished();
|
self.previous.cleanup_finished();
|
||||||
}
|
}
|
||||||
@ -412,7 +398,6 @@ where
|
|||||||
self.build_submission_impl()
|
self.build_submission_impl()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let mut submitted = self.submitted.lock();
|
let mut submitted = self.submitted.lock();
|
||||||
@ -436,23 +421,19 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
self.finished.store(true, Ordering::SeqCst);
|
self.finished.store(true, Ordering::SeqCst);
|
||||||
self.previous.signal_finished();
|
self.previous.signal_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
Some(self.queue.clone())
|
Some(self.queue.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -472,7 +453,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -511,7 +491,6 @@ unsafe impl<F> DeviceOwned for CommandBufferExecFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.command_buffer.device()
|
self.command_buffer.device()
|
||||||
}
|
}
|
||||||
@ -556,32 +535,30 @@ pub enum CommandBufferExecError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for CommandBufferExecError {
|
impl Error for CommandBufferExecError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
CommandBufferExecError::AccessError { ref error, .. } => Some(error),
|
CommandBufferExecError::AccessError { error, .. } => Some(error),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for CommandBufferExecError {
|
impl Display for CommandBufferExecError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
CommandBufferExecError::AccessError { .. } =>
|
CommandBufferExecError::AccessError { .. } =>
|
||||||
"access to a resource has been denied",
|
"access to a resource has been denied",
|
||||||
CommandBufferExecError::OneTimeSubmitAlreadySubmitted => {
|
CommandBufferExecError::OneTimeSubmitAlreadySubmitted => {
|
||||||
"the command buffer or one of the secondary command buffers it executes was \
|
"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 \
|
created with the \"one time submit\" flag, but has already been submitted in \
|
||||||
the past"
|
the past"
|
||||||
}
|
}
|
||||||
CommandBufferExecError::ExclusiveAlreadyInUse => {
|
CommandBufferExecError::ExclusiveAlreadyInUse => {
|
||||||
"the command buffer or one of the secondary command buffers it executes is \
|
"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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -25,7 +25,6 @@ unsafe impl<T> DescriptorSetsCollection for T
|
|||||||
where
|
where
|
||||||
T: Into<DescriptorSetWithOffsets>,
|
T: Into<DescriptorSetWithOffsets>,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
|
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
|
||||||
vec![self.into()]
|
vec![self.into()]
|
||||||
}
|
}
|
||||||
@ -35,7 +34,6 @@ unsafe impl<T> DescriptorSetsCollection for Vec<T>
|
|||||||
where
|
where
|
||||||
T: Into<DescriptorSetWithOffsets>,
|
T: Into<DescriptorSetWithOffsets>,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
|
fn into_vec(self) -> Vec<DescriptorSetWithOffsets> {
|
||||||
self.into_iter().map(|x| x.into()).collect()
|
self.into_iter().map(|x| x.into()).collect()
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ pub struct DescriptorSetLayout {
|
|||||||
|
|
||||||
impl DescriptorSetLayout {
|
impl DescriptorSetLayout {
|
||||||
/// Creates a new `DescriptorSetLayout`.
|
/// Creates a new `DescriptorSetLayout`.
|
||||||
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
mut create_info: DescriptorSetLayoutCreateInfo,
|
mut create_info: DescriptorSetLayoutCreateInfo,
|
||||||
@ -73,6 +74,7 @@ impl DescriptorSetLayout {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::DescriptorSetLayout,
|
handle: ash::vk::DescriptorSetLayout,
|
||||||
@ -461,7 +463,6 @@ impl PartialEq for DescriptorSetLayout {
|
|||||||
impl Eq for DescriptorSetLayout {}
|
impl Eq for DescriptorSetLayout {}
|
||||||
|
|
||||||
impl Hash for DescriptorSetLayout {
|
impl Hash for DescriptorSetLayout {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -520,13 +521,11 @@ impl From<VulkanError> for DescriptorSetLayoutCreationError {
|
|||||||
impl Error for DescriptorSetLayoutCreationError {}
|
impl Error for DescriptorSetLayoutCreationError {}
|
||||||
|
|
||||||
impl Display for DescriptorSetLayoutCreationError {
|
impl Display for DescriptorSetLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => {
|
Self::OomError(_) => {
|
||||||
write!(f, "out of memory")
|
write!(f, "out of memory")
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -535,15 +534,20 @@ impl Display for DescriptorSetLayoutCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::ImmutableSamplersCountMismatch {
|
||||||
Self::ImmutableSamplersCountMismatch { binding_num, sampler_count, descriptor_count } => write!(
|
binding_num,
|
||||||
|
sampler_count,
|
||||||
|
descriptor_count,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
binding_num, sampler_count, descriptor_count,
|
||||||
),
|
),
|
||||||
Self::ImmutableSamplersDescriptorTypeIncompatible { binding_num } => write!(
|
Self::ImmutableSamplersDescriptorTypeIncompatible { binding_num } => write!(
|
||||||
f,
|
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,
|
binding_num,
|
||||||
),
|
),
|
||||||
Self::MaxPushDescriptorsExceeded {
|
Self::MaxPushDescriptorsExceeded {
|
||||||
@ -551,27 +555,35 @@ impl Display for DescriptorSetLayoutCreationError {
|
|||||||
max_supported,
|
max_supported,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::PushDescriptorDescriptorTypeIncompatible { binding_num } => write!(
|
Self::PushDescriptorDescriptorTypeIncompatible { binding_num } => write!(
|
||||||
f,
|
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,
|
binding_num,
|
||||||
),
|
),
|
||||||
Self::PushDescriptorVariableDescriptorCount { binding_num } => write!(
|
Self::PushDescriptorVariableDescriptorCount { binding_num } => write!(
|
||||||
f,
|
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,
|
binding_num,
|
||||||
),
|
),
|
||||||
Self::VariableDescriptorCountBindingNotHighest { binding_num, highest_binding_num } => write!(
|
Self::VariableDescriptorCountBindingNotHighest {
|
||||||
|
binding_num,
|
||||||
|
highest_binding_num,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
binding_num, highest_binding_num,
|
||||||
),
|
),
|
||||||
Self::VariableDescriptorCountDescriptorTypeIncompatible { binding_num } => write!(
|
Self::VariableDescriptorCountDescriptorTypeIncompatible { binding_num } => write!(
|
||||||
f,
|
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,
|
binding_num,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -579,7 +591,6 @@ impl Display for DescriptorSetLayoutCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for DescriptorSetLayoutCreationError {
|
impl From<RequirementNotMet> for DescriptorSetLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -633,7 +644,6 @@ impl Default for DescriptorSetLayoutCreateInfo {
|
|||||||
impl DescriptorSetLayoutCreateInfo {
|
impl DescriptorSetLayoutCreateInfo {
|
||||||
/// Builds a list of `DescriptorSetLayoutCreateInfo` from an iterator of `DescriptorRequirement`
|
/// Builds a list of `DescriptorSetLayoutCreateInfo` from an iterator of `DescriptorRequirement`
|
||||||
/// originating from a shader.
|
/// originating from a shader.
|
||||||
#[inline]
|
|
||||||
pub fn from_requirements<'a>(
|
pub fn from_requirements<'a>(
|
||||||
descriptor_requirements: impl IntoIterator<Item = ((u32, u32), &'a DescriptorRequirements)>,
|
descriptor_requirements: impl IntoIterator<Item = ((u32, u32), &'a DescriptorRequirements)>,
|
||||||
) -> Vec<Self> {
|
) -> Vec<Self> {
|
||||||
@ -671,16 +681,17 @@ pub struct DescriptorSetLayoutBinding {
|
|||||||
|
|
||||||
/// Whether the binding has a variable number of descriptors.
|
/// Whether the binding has a variable number of descriptors.
|
||||||
///
|
///
|
||||||
/// If set to `true`, the
|
/// If set to `true`, the [`descriptor_binding_variable_descriptor_count`] feature must be
|
||||||
/// [`descriptor_binding_variable_descriptor_count`](crate::device::Features::descriptor_binding_variable_descriptor_count)
|
/// enabled. The value of `descriptor_count` specifies the maximum number of descriptors
|
||||||
/// feature must be enabled. The value of `descriptor_count` specifies the maximum number of
|
/// allowed.
|
||||||
/// descriptors allowed.
|
|
||||||
///
|
///
|
||||||
/// There may only be one binding with a variable count in a descriptor set, and it must be the
|
/// 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
|
/// binding with the highest binding number. The `descriptor_type` must not be
|
||||||
/// [`DescriptorType::UniformBufferDynamic`] or [`DescriptorType::StorageBufferDynamic`].
|
/// [`DescriptorType::UniformBufferDynamic`] or [`DescriptorType::StorageBufferDynamic`].
|
||||||
///
|
///
|
||||||
/// The default value is `false`.
|
/// The default value is `false`.
|
||||||
|
///
|
||||||
|
/// [`descriptor_binding_variable_descriptor_count`]: crate::device::Features::descriptor_binding_variable_descriptor_count
|
||||||
pub variable_descriptor_count: bool,
|
pub variable_descriptor_count: bool,
|
||||||
|
|
||||||
/// Which shader stages are going to access the descriptors in this binding.
|
/// Which shader stages are going to access the descriptors in this binding.
|
||||||
@ -768,6 +779,7 @@ impl DescriptorSetLayoutBinding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<&DescriptorRequirements> for DescriptorSetLayoutBinding {
|
impl From<&DescriptorRequirements> for DescriptorSetLayoutBinding {
|
||||||
|
#[inline]
|
||||||
fn from(reqs: &DescriptorRequirements) -> Self {
|
fn from(reqs: &DescriptorRequirements) -> Self {
|
||||||
Self {
|
Self {
|
||||||
descriptor_type: reqs.descriptor_types[0],
|
descriptor_type: reqs.descriptor_types[0],
|
||||||
@ -802,18 +814,17 @@ pub enum DescriptorRequirementsNotMet {
|
|||||||
impl Error for DescriptorRequirementsNotMet {}
|
impl Error for DescriptorRequirementsNotMet {}
|
||||||
|
|
||||||
impl Display for DescriptorRequirementsNotMet {
|
impl Display for DescriptorRequirementsNotMet {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::DescriptorType { required, obtained } => write!(
|
Self::DescriptorType { required, obtained } => write!(
|
||||||
f,
|
f,
|
||||||
"the descriptor's type ({:?}) is not one of those required ({:?})",
|
"the descriptor's type ({:?}) is not one of those required ({:?})",
|
||||||
obtained, required
|
obtained, required,
|
||||||
),
|
),
|
||||||
Self::DescriptorCount { required, obtained } => write!(
|
Self::DescriptorCount { required, obtained } => write!(
|
||||||
f,
|
f,
|
||||||
"the descriptor count ({}) is less than what is required ({})",
|
"the descriptor count ({}) is less than what is required ({})",
|
||||||
obtained, required
|
obtained, required,
|
||||||
),
|
),
|
||||||
Self::ShaderStages { .. } => write!(
|
Self::ShaderStages { .. } => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
//! that are often used together in the same set so that you can keep the same set binding through
|
//! that are often used together in the same set so that you can keep the same set binding through
|
||||||
//! multiple draws.
|
//! multiple draws.
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! > **Note**: This section describes the simple way to bind resources. There are more optimized
|
//! > **Note**: This section describes the simple way to bind resources. There are more optimized
|
||||||
//! > ways.
|
//! > ways.
|
||||||
@ -143,7 +143,6 @@ impl PartialEq for dyn DescriptorSet {
|
|||||||
impl Eq for dyn DescriptorSet {}
|
impl Eq for dyn DescriptorSet {}
|
||||||
|
|
||||||
impl Hash for dyn DescriptorSet {
|
impl Hash for dyn DescriptorSet {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().internal_object().hash(state);
|
self.inner().internal_object().hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -164,14 +163,16 @@ impl DescriptorSetInner {
|
|||||||
) -> Result<Self, DescriptorSetUpdateError> {
|
) -> Result<Self, DescriptorSetUpdateError> {
|
||||||
assert!(
|
assert!(
|
||||||
!layout.push_descriptor(),
|
!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();
|
let max_count = layout.variable_descriptor_count();
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
variable_descriptor_count <= max_count,
|
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,
|
variable_descriptor_count,
|
||||||
max_count,
|
max_count,
|
||||||
);
|
);
|
||||||
@ -247,6 +248,7 @@ pub struct DescriptorSetResources {
|
|||||||
impl DescriptorSetResources {
|
impl DescriptorSetResources {
|
||||||
/// Creates a new `DescriptorSetResources` matching the provided descriptor set layout, and
|
/// Creates a new `DescriptorSetResources` matching the provided descriptor set layout, and
|
||||||
/// all descriptors set to `None`.
|
/// all descriptors set to `None`.
|
||||||
|
#[inline]
|
||||||
pub fn new(layout: &DescriptorSetLayout, variable_descriptor_count: u32) -> Self {
|
pub fn new(layout: &DescriptorSetLayout, variable_descriptor_count: u32) -> Self {
|
||||||
assert!(variable_descriptor_count <= layout.variable_descriptor_count());
|
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.
|
/// - Panics if the binding number of a write does not exist in the resources.
|
||||||
/// - See also [`DescriptorBindingResources::update`].
|
/// - See also [`DescriptorBindingResources::update`].
|
||||||
|
#[inline]
|
||||||
pub fn update(&mut self, write: &WriteDescriptorSet) {
|
pub fn update(&mut self, write: &WriteDescriptorSet) {
|
||||||
self.binding_resources
|
self.binding_resources
|
||||||
.get_mut(&write.binding())
|
.get_mut(&write.binding())
|
||||||
@ -344,6 +347,7 @@ impl DescriptorBindingResources {
|
|||||||
///
|
///
|
||||||
/// - Panics if the resource types do not match.
|
/// - Panics if the resource types do not match.
|
||||||
/// - Panics if the write goes out of bounds.
|
/// - Panics if the write goes out of bounds.
|
||||||
|
#[inline]
|
||||||
pub fn update(&mut self, write: &WriteDescriptorSet) {
|
pub fn update(&mut self, write: &WriteDescriptorSet) {
|
||||||
fn write_resources<T: Clone>(first: usize, resources: &mut [Option<T>], elements: &[T]) {
|
fn write_resources<T: Clone>(first: usize, resources: &mut [Option<T>], elements: &[T]) {
|
||||||
resources
|
resources
|
||||||
@ -406,7 +410,6 @@ pub struct DescriptorSetWithOffsets {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DescriptorSetWithOffsets {
|
impl DescriptorSetWithOffsets {
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
descriptor_set: Arc<dyn DescriptorSet>,
|
descriptor_set: Arc<dyn DescriptorSet>,
|
||||||
dynamic_offsets: impl IntoIterator<Item = u32>,
|
dynamic_offsets: impl IntoIterator<Item = u32>,
|
||||||
@ -428,9 +431,10 @@ impl DescriptorSetWithOffsets {
|
|||||||
if dynamic_offsets.len() > dynamic_offset_index {
|
if dynamic_offsets.len() > dynamic_offset_index {
|
||||||
assert!(
|
assert!(
|
||||||
dynamic_offsets[dynamic_offset_index] % min_storage_off_align == 0,
|
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],
|
dynamic_offsets[dynamic_offset_index],
|
||||||
min_storage_off_align
|
min_storage_off_align,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
dynamic_offset_index += 1;
|
dynamic_offset_index += 1;
|
||||||
@ -440,9 +444,10 @@ impl DescriptorSetWithOffsets {
|
|||||||
if dynamic_offsets.len() > dynamic_offset_index {
|
if dynamic_offsets.len() > dynamic_offset_index {
|
||||||
assert!(
|
assert!(
|
||||||
dynamic_offsets[dynamic_offset_index] % min_uniform_off_align == 0,
|
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],
|
dynamic_offsets[dynamic_offset_index],
|
||||||
min_uniform_off_align
|
min_uniform_off_align,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
dynamic_offset_index += 1;
|
dynamic_offset_index += 1;
|
||||||
@ -455,13 +460,13 @@ impl DescriptorSetWithOffsets {
|
|||||||
dynamic_offsets.len() >= dynamic_offset_index,
|
dynamic_offsets.len() >= dynamic_offset_index,
|
||||||
"Too few dynamic offsets: got {}, expected {}",
|
"Too few dynamic offsets: got {}, expected {}",
|
||||||
dynamic_offsets.len(),
|
dynamic_offsets.len(),
|
||||||
dynamic_offset_index
|
dynamic_offset_index,
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
dynamic_offsets.len() <= dynamic_offset_index,
|
dynamic_offsets.len() <= dynamic_offset_index,
|
||||||
"Too many dynamic offsets: got {}, expected {}",
|
"Too many dynamic offsets: got {}, expected {}",
|
||||||
dynamic_offsets.len(),
|
dynamic_offsets.len(),
|
||||||
dynamic_offset_index
|
dynamic_offset_index,
|
||||||
);
|
);
|
||||||
|
|
||||||
DescriptorSetWithOffsets {
|
DescriptorSetWithOffsets {
|
||||||
@ -485,7 +490,6 @@ impl<S> From<Arc<S>> for DescriptorSetWithOffsets
|
|||||||
where
|
where
|
||||||
S: DescriptorSet + 'static,
|
S: DescriptorSet + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn from(descriptor_set: Arc<S>) -> Self {
|
fn from(descriptor_set: Arc<S>) -> Self {
|
||||||
DescriptorSetWithOffsets::new(descriptor_set, std::iter::empty())
|
DescriptorSetWithOffsets::new(descriptor_set, std::iter::empty())
|
||||||
}
|
}
|
||||||
@ -498,7 +502,6 @@ pub enum DescriptorSetCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for DescriptorSetCreationError {
|
impl Error for DescriptorSetCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::DescriptorSetUpdateError(err) => Some(err),
|
Self::DescriptorSetUpdateError(err) => Some(err),
|
||||||
@ -508,7 +511,6 @@ impl Error for DescriptorSetCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DescriptorSetCreationError {
|
impl Display for DescriptorSetCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::DescriptorSetUpdateError(_) => {
|
Self::DescriptorSetUpdateError(_) => {
|
||||||
@ -520,14 +522,12 @@ impl Display for DescriptorSetCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<DescriptorSetUpdateError> for DescriptorSetCreationError {
|
impl From<DescriptorSetUpdateError> for DescriptorSetCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DescriptorSetUpdateError) -> Self {
|
fn from(err: DescriptorSetUpdateError) -> Self {
|
||||||
Self::DescriptorSetUpdateError(err)
|
Self::DescriptorSetUpdateError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for DescriptorSetCreationError {
|
impl From<OomError> for DescriptorSetCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
//! > actual allocation, you can skip this allocation and make it acceptable to use a persistent
|
//! > actual allocation, you can skip this allocation and make it acceptable to use a persistent
|
||||||
//! > descriptor set in performance-critical paths..
|
//! > descriptor set in performance-critical paths..
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Examples
|
||||||
//! TODO:
|
//! TODO:
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -124,17 +124,14 @@ unsafe impl<P> DescriptorSet for PersistentDescriptorSet<P>
|
|||||||
where
|
where
|
||||||
P: DescriptorPoolAlloc,
|
P: DescriptorPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeDescriptorSet {
|
fn inner(&self) -> &UnsafeDescriptorSet {
|
||||||
self.alloc.inner()
|
self.alloc.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn layout(&self) -> &Arc<DescriptorSetLayout> {
|
fn layout(&self) -> &Arc<DescriptorSetLayout> {
|
||||||
self.inner.layout()
|
self.inner.layout()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn resources(&self) -> &DescriptorSetResources {
|
fn resources(&self) -> &DescriptorSetResources {
|
||||||
self.inner.resources()
|
self.inner.resources()
|
||||||
}
|
}
|
||||||
@ -144,7 +141,6 @@ unsafe impl<P> DeviceOwned for PersistentDescriptorSet<P>
|
|||||||
where
|
where
|
||||||
P: DescriptorPoolAlloc,
|
P: DescriptorPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.inner.layout().device()
|
self.inner.layout().device()
|
||||||
}
|
}
|
||||||
@ -154,7 +150,6 @@ impl<P> PartialEq for PersistentDescriptorSet<P>
|
|||||||
where
|
where
|
||||||
P: DescriptorPoolAlloc,
|
P: DescriptorPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner().internal_object() == other.inner().internal_object()
|
self.inner().internal_object() == other.inner().internal_object()
|
||||||
&& self.device() == other.device()
|
&& self.device() == other.device()
|
||||||
@ -167,7 +162,6 @@ impl<P> Hash for PersistentDescriptorSet<P>
|
|||||||
where
|
where
|
||||||
P: DescriptorPoolAlloc,
|
P: DescriptorPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().internal_object().hash(state);
|
self.inner().internal_object().hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
|
@ -41,6 +41,7 @@ enum Pool {
|
|||||||
|
|
||||||
impl StandardDescriptorPool {
|
impl StandardDescriptorPool {
|
||||||
/// Builds a new `StandardDescriptorPool`.
|
/// Builds a new `StandardDescriptorPool`.
|
||||||
|
#[inline]
|
||||||
pub fn new(device: Arc<Device>) -> StandardDescriptorPool {
|
pub fn new(device: Arc<Device>) -> StandardDescriptorPool {
|
||||||
StandardDescriptorPool {
|
StandardDescriptorPool {
|
||||||
device,
|
device,
|
||||||
@ -52,6 +53,7 @@ impl StandardDescriptorPool {
|
|||||||
unsafe impl DescriptorPool for StandardDescriptorPool {
|
unsafe impl DescriptorPool for StandardDescriptorPool {
|
||||||
type Alloc = StandardDescriptorPoolAlloc;
|
type Alloc = StandardDescriptorPoolAlloc;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn allocate(
|
fn allocate(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &Arc<DescriptorSetLayout>,
|
layout: &Arc<DescriptorSetLayout>,
|
||||||
|
@ -124,6 +124,7 @@ impl UnsafeDescriptorPool {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::DescriptorPool,
|
handle: ash::vk::DescriptorPool,
|
||||||
@ -170,7 +171,7 @@ impl UnsafeDescriptorPool {
|
|||||||
/// The `FragmentedPool` errors often can't be prevented. If the function returns this error,
|
/// The `FragmentedPool` errors often can't be prevented. If the function returns this error,
|
||||||
/// you should just create a new pool.
|
/// 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.
|
/// - 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.
|
/// - 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
|
/// - 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.
|
/// is destroyed, as destroying the pool is equivalent to freeing all the sets.
|
||||||
///
|
|
||||||
pub unsafe fn allocate_descriptor_sets<'a>(
|
pub unsafe fn allocate_descriptor_sets<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocate_info: impl IntoIterator<Item = DescriptorSetAllocateInfo<'a>>,
|
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 have been allocated from the pool.
|
||||||
/// - The descriptor sets must not be free'd twice.
|
/// - The descriptor sets must not be free'd twice.
|
||||||
/// - The descriptor sets must not be in use by the GPU.
|
/// - The descriptor sets must not be in use by the GPU.
|
||||||
///
|
|
||||||
pub unsafe fn free_descriptor_sets(
|
pub unsafe fn free_descriptor_sets(
|
||||||
&mut self,
|
&mut self,
|
||||||
descriptor_sets: impl IntoIterator<Item = UnsafeDescriptorSet>,
|
descriptor_sets: impl IntoIterator<Item = UnsafeDescriptorSet>,
|
||||||
@ -308,6 +307,7 @@ impl UnsafeDescriptorPool {
|
|||||||
/// Resets the pool.
|
/// Resets the pool.
|
||||||
///
|
///
|
||||||
/// This destroys all descriptor sets and empties the pool.
|
/// This destroys all descriptor sets and empties the pool.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn reset(&mut self) -> Result<(), OomError> {
|
pub unsafe fn reset(&mut self) -> Result<(), OomError> {
|
||||||
let fns = self.device.fns();
|
let fns = self.device.fns();
|
||||||
(fns.v1_0.reset_descriptor_pool)(
|
(fns.v1_0.reset_descriptor_pool)(
|
||||||
@ -317,6 +317,7 @@ impl UnsafeDescriptorPool {
|
|||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -361,7 +362,6 @@ impl PartialEq for UnsafeDescriptorPool {
|
|||||||
impl Eq for UnsafeDescriptorPool {}
|
impl Eq for UnsafeDescriptorPool {}
|
||||||
|
|
||||||
impl Hash for UnsafeDescriptorPool {
|
impl Hash for UnsafeDescriptorPool {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -429,12 +429,11 @@ pub enum DescriptorPoolAllocError {
|
|||||||
impl Error for DescriptorPoolAllocError {}
|
impl Error for DescriptorPoolAllocError {}
|
||||||
|
|
||||||
impl Display for DescriptorPoolAllocError {
|
impl Display for DescriptorPoolAllocError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
DescriptorPoolAllocError::OutOfHostMemory => "no memory available on the host",
|
DescriptorPoolAllocError::OutOfHostMemory => "no memory available on the host",
|
||||||
DescriptorPoolAllocError::OutOfDeviceMemory => {
|
DescriptorPoolAllocError::OutOfDeviceMemory => {
|
||||||
"no memory available on the graphical device"
|
"no memory available on the graphical device"
|
||||||
|
@ -60,6 +60,7 @@ impl SingleLayoutDescSetPool {
|
|||||||
/// - Panics if the provided `layout` is for push descriptors rather than regular descriptor
|
/// - Panics if the provided `layout` is for push descriptors rather than regular descriptor
|
||||||
/// sets.
|
/// sets.
|
||||||
/// - Panics if the provided `layout` has a binding with a variable descriptor count.
|
/// - Panics if the provided `layout` has a binding with a variable descriptor count.
|
||||||
|
#[inline]
|
||||||
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
|
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
|
||||||
assert!(
|
assert!(
|
||||||
!layout.push_descriptor(),
|
!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
|
/// Returns a new descriptor set, either by creating a new one or returning an existing one
|
||||||
/// from the internal reserve.
|
/// from the internal reserve.
|
||||||
#[inline]
|
|
||||||
pub fn next(
|
pub fn next(
|
||||||
&mut self,
|
&mut self,
|
||||||
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
descriptor_writes: impl IntoIterator<Item = WriteDescriptorSet>,
|
||||||
@ -186,12 +186,10 @@ pub(crate) struct SingleLayoutPoolAlloc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DescriptorPoolAlloc for SingleLayoutPoolAlloc {
|
impl DescriptorPoolAlloc for SingleLayoutPoolAlloc {
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeDescriptorSet {
|
fn inner(&self) -> &UnsafeDescriptorSet {
|
||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
|
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
|
||||||
&mut self.inner
|
&mut self.inner
|
||||||
}
|
}
|
||||||
@ -245,7 +243,6 @@ impl PartialEq for SingleLayoutDescSet {
|
|||||||
impl Eq for SingleLayoutDescSet {}
|
impl Eq for SingleLayoutDescSet {}
|
||||||
|
|
||||||
impl Hash for SingleLayoutDescSet {
|
impl Hash for SingleLayoutDescSet {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().internal_object().hash(state);
|
self.inner().internal_object().hash(state);
|
||||||
self.device().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
|
/// - Panics if the provided `layout` is for push descriptors rather than regular descriptor
|
||||||
/// sets.
|
/// sets.
|
||||||
|
#[inline]
|
||||||
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
|
pub fn new(layout: Arc<DescriptorSetLayout>) -> Result<Self, OomError> {
|
||||||
assert!(
|
assert!(
|
||||||
!layout.push_descriptor(),
|
!layout.push_descriptor(),
|
||||||
@ -301,7 +299,6 @@ impl SingleLayoutVariableDescSetPool {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the provided `variable_descriptor_count` exceeds the maximum for the layout.
|
/// - Panics if the provided `variable_descriptor_count` exceeds the maximum for the layout.
|
||||||
#[inline]
|
|
||||||
pub fn next(
|
pub fn next(
|
||||||
&mut self,
|
&mut self,
|
||||||
variable_descriptor_count: u32,
|
variable_descriptor_count: u32,
|
||||||
@ -440,12 +437,10 @@ unsafe impl Send for SingleLayoutVariablePoolAlloc {}
|
|||||||
unsafe impl Sync for SingleLayoutVariablePoolAlloc {}
|
unsafe impl Sync for SingleLayoutVariablePoolAlloc {}
|
||||||
|
|
||||||
impl DescriptorPoolAlloc for SingleLayoutVariablePoolAlloc {
|
impl DescriptorPoolAlloc for SingleLayoutVariablePoolAlloc {
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> &UnsafeDescriptorSet {
|
fn inner(&self) -> &UnsafeDescriptorSet {
|
||||||
&self.inner
|
&self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
|
fn inner_mut(&mut self) -> &mut UnsafeDescriptorSet {
|
||||||
&mut self.inner
|
&mut self.inner
|
||||||
}
|
}
|
||||||
@ -492,7 +487,6 @@ impl PartialEq for SingleLayoutVariableDescSet {
|
|||||||
impl Eq for SingleLayoutVariableDescSet {}
|
impl Eq for SingleLayoutVariableDescSet {}
|
||||||
|
|
||||||
impl Hash for SingleLayoutVariableDescSet {
|
impl Hash for SingleLayoutVariableDescSet {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().internal_object().hash(state);
|
self.inner().internal_object().hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
|
@ -48,7 +48,6 @@ impl UnsafeDescriptorSet {
|
|||||||
/// - Updating a descriptor set obeys synchronization rules that aren't checked here. Once a
|
/// - 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
|
/// command buffer contains a pointer/reference to a descriptor set, it is illegal to write
|
||||||
/// to it.
|
/// to it.
|
||||||
///
|
|
||||||
pub unsafe fn write<'a>(
|
pub unsafe fn write<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
layout: &DescriptorSetLayout,
|
layout: &DescriptorSetLayout,
|
||||||
|
@ -72,7 +72,6 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive buffer elements.
|
/// Write a number of consecutive buffer elements.
|
||||||
#[inline]
|
|
||||||
pub fn buffer_array(
|
pub fn buffer_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
@ -94,7 +93,6 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive buffer view elements.
|
/// Write a number of consecutive buffer view elements.
|
||||||
#[inline]
|
|
||||||
pub fn buffer_view_array(
|
pub fn buffer_view_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
@ -116,7 +114,6 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive image view elements.
|
/// Write a number of consecutive image view elements.
|
||||||
#[inline]
|
|
||||||
pub fn image_view_array(
|
pub fn image_view_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
@ -142,7 +139,6 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive image view and sampler elements.
|
/// Write a number of consecutive image view and sampler elements.
|
||||||
#[inline]
|
|
||||||
pub fn image_view_sampler_array(
|
pub fn image_view_sampler_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
@ -164,7 +160,6 @@ impl WriteDescriptorSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Write a number of consecutive sampler elements.
|
/// Write a number of consecutive sampler elements.
|
||||||
#[inline]
|
|
||||||
pub fn sampler_array(
|
pub fn sampler_array(
|
||||||
binding: u32,
|
binding: u32,
|
||||||
first_array_element: u32,
|
first_array_element: u32,
|
||||||
@ -949,7 +944,6 @@ impl Error for DescriptorSetUpdateError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DescriptorSetUpdateError {
|
impl Display for DescriptorSetUpdateError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::ArrayIndexOutOfBounds {
|
Self::ArrayIndexOutOfBounds {
|
||||||
@ -958,66 +952,75 @@ impl Display for DescriptorSetUpdateError {
|
|||||||
written_count,
|
written_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
written_count, binding, available_count,
|
||||||
),
|
),
|
||||||
Self::ImageView2dFrom3d { binding, index } => write!(
|
Self::ImageView2dFrom3d { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::ImageViewDepthAndStencil { binding, index } => write!(
|
Self::ImageViewDepthAndStencil { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::ImageViewHasSamplerYcbcrConversion { binding, index } => write!(
|
Self::ImageViewHasSamplerYcbcrConversion { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::ImageViewIsArrayed { binding, index } => write!(
|
Self::ImageViewIsArrayed { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::ImageViewIncompatibleSampler { binding, index, .. } => write!(
|
Self::ImageViewIncompatibleSampler { binding, index, .. } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::ImageViewNotIdentitySwizzled { binding, index } => write!(
|
Self::ImageViewNotIdentitySwizzled { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::IncompatibleDescriptorType { binding } => write!(
|
Self::IncompatibleDescriptorType { binding } => write!(
|
||||||
f,
|
f,
|
||||||
"tried to write a resource to binding {} whose type was not compatible with the descriptor type",
|
"tried to write a resource to binding {} whose type was not compatible with the \
|
||||||
binding,
|
descriptor type",
|
||||||
),
|
|
||||||
Self::InvalidBinding { binding } => write!(
|
|
||||||
f,
|
|
||||||
"tried to write to a nonexistent binding {}",
|
|
||||||
binding,
|
binding,
|
||||||
),
|
),
|
||||||
|
Self::InvalidBinding { binding } => {
|
||||||
|
write!(f, "tried to write to a nonexistent binding {}", binding,)
|
||||||
|
}
|
||||||
Self::MissingUsage {
|
Self::MissingUsage {
|
||||||
binding,
|
binding,
|
||||||
index,
|
index,
|
||||||
usage,
|
usage,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
binding, index, usage,
|
||||||
),
|
),
|
||||||
Self::SamplerHasSamplerYcbcrConversion { binding, index } => write!(
|
Self::SamplerHasSamplerYcbcrConversion { binding, index } => write!(
|
||||||
f,
|
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,
|
binding, index,
|
||||||
),
|
),
|
||||||
Self::SamplerIsImmutable { binding } => write!(
|
Self::SamplerIsImmutable { binding } => write!(
|
||||||
f,
|
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,
|
binding,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ pub struct FeatureRestrictionError {
|
|||||||
impl Error for FeatureRestrictionError {}
|
impl Error for FeatureRestrictionError {}
|
||||||
|
|
||||||
impl Display for FeatureRestrictionError {
|
impl Display for FeatureRestrictionError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
@ -50,7 +49,6 @@ pub enum FeatureRestriction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FeatureRestriction {
|
impl Display for FeatureRestriction {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match *self {
|
||||||
FeatureRestriction::NotSupported => {
|
FeatureRestriction::NotSupported => {
|
||||||
|
@ -611,6 +611,7 @@ impl Device {
|
|||||||
///
|
///
|
||||||
/// - `file` must be a handle to external memory that was created outside the Vulkan API.
|
/// - `file` must be a handle to external memory that was created outside the Vulkan API.
|
||||||
#[cfg_attr(not(unix), allow(unused_variables))]
|
#[cfg_attr(not(unix), allow(unused_variables))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn memory_fd_properties(
|
pub unsafe fn memory_fd_properties(
|
||||||
&self,
|
&self,
|
||||||
handle_type: ExternalMemoryHandleType,
|
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
|
/// 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)
|
/// of the device (either explicitly or implicitly, for example with a future's destructor)
|
||||||
/// while this function is waiting.
|
/// while this function is waiting.
|
||||||
///
|
#[inline]
|
||||||
pub unsafe fn wait_idle(&self) -> Result<(), OomError> {
|
pub unsafe fn wait_idle(&self) -> Result<(), OomError> {
|
||||||
let fns = self.fns();
|
let fns = self.fns();
|
||||||
(fns.v1_0.device_wait_idle)(self.handle)
|
(fns.v1_0.device_wait_idle)(self.handle)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -743,7 +745,6 @@ impl PartialEq for Device {
|
|||||||
impl Eq for Device {}
|
impl Eq for Device {}
|
||||||
|
|
||||||
impl Hash for Device {
|
impl Hash for Device {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.physical_device.hash(state);
|
self.physical_device.hash(state);
|
||||||
@ -781,15 +782,12 @@ pub enum DeviceCreationError {
|
|||||||
impl Error for DeviceCreationError {}
|
impl Error for DeviceCreationError {}
|
||||||
|
|
||||||
impl Display for DeviceCreationError {
|
impl Display for DeviceCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::InitializationFailed => {
|
Self::InitializationFailed => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"failed to create the device for an implementation-specific reason",
|
||||||
"failed to create the device for an implementation-specific reason"
|
),
|
||||||
)
|
|
||||||
}
|
|
||||||
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
|
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
|
||||||
Self::OutOfDeviceMemory => {
|
Self::OutOfDeviceMemory => {
|
||||||
write!(f, "no memory available on the graphical device")
|
write!(f, "no memory available on the graphical device")
|
||||||
@ -798,24 +796,23 @@ impl Display for DeviceCreationError {
|
|||||||
Self::TooManyQueuesForFamily => {
|
Self::TooManyQueuesForFamily => {
|
||||||
write!(f, "tried to create too many queues for a given family")
|
write!(f, "tried to create too many queues for a given family")
|
||||||
}
|
}
|
||||||
Self::FeatureNotPresent => {
|
Self::FeatureNotPresent => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"some of the requested features are unsupported by the physical device",
|
||||||
"some of the requested features are unsupported by the physical device"
|
),
|
||||||
)
|
Self::PriorityOutOfRange => write!(
|
||||||
}
|
f,
|
||||||
Self::PriorityOutOfRange => {
|
"the priority of one of the queues is out of the [0.0; 1.0] range",
|
||||||
write!(
|
),
|
||||||
f,
|
Self::ExtensionNotPresent => write!(
|
||||||
"the priority of one of the queues is out of the [0.0; 1.0] range"
|
f,
|
||||||
)
|
"some of the requested device extensions are not supported by the physical device",
|
||||||
}
|
),
|
||||||
Self::ExtensionNotPresent => {
|
Self::TooManyObjects => write!(
|
||||||
write!(f,"some of the requested device extensions are not supported by the physical device")
|
f,
|
||||||
}
|
"you have reached the limit to the number of devices that can be created from the \
|
||||||
Self::TooManyObjects => {
|
same physical device",
|
||||||
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::ExtensionRestrictionNotMet(err) => err.fmt(f),
|
||||||
Self::FeatureRestrictionNotMet(err) => err.fmt(f),
|
Self::FeatureRestrictionNotMet(err) => err.fmt(f),
|
||||||
}
|
}
|
||||||
@ -823,7 +820,6 @@ impl Display for DeviceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for DeviceCreationError {
|
impl From<VulkanError> for DeviceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
VulkanError::InitializationFailed => Self::InitializationFailed,
|
VulkanError::InitializationFailed => Self::InitializationFailed,
|
||||||
@ -839,14 +835,12 @@ impl From<VulkanError> for DeviceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExtensionRestrictionError> for DeviceCreationError {
|
impl From<ExtensionRestrictionError> for DeviceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: ExtensionRestrictionError) -> Self {
|
fn from(err: ExtensionRestrictionError) -> Self {
|
||||||
Self::ExtensionRestrictionNotMet(err)
|
Self::ExtensionRestrictionNotMet(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<FeatureRestrictionError> for DeviceCreationError {
|
impl From<FeatureRestrictionError> for DeviceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: FeatureRestrictionError) -> Self {
|
fn from(err: FeatureRestrictionError) -> Self {
|
||||||
Self::FeatureRestrictionNotMet(err)
|
Self::FeatureRestrictionNotMet(err)
|
||||||
}
|
}
|
||||||
@ -922,7 +916,6 @@ impl Default for QueueCreateInfo {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `device()` must return the correct device.
|
/// - `device()` must return the correct device.
|
||||||
///
|
|
||||||
pub unsafe trait DeviceOwned {
|
pub unsafe trait DeviceOwned {
|
||||||
/// Returns the device that owns `Self`.
|
/// Returns the device that owns `Self`.
|
||||||
fn device(&self) -> &Arc<Device>;
|
fn device(&self) -> &Arc<Device>;
|
||||||
@ -933,7 +926,6 @@ where
|
|||||||
T: Deref,
|
T: Deref,
|
||||||
T::Target: DeviceOwned,
|
T::Target: DeviceOwned,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
(**self).device()
|
(**self).device()
|
||||||
}
|
}
|
||||||
@ -971,11 +963,9 @@ pub enum MemoryFdPropertiesError {
|
|||||||
impl Error for MemoryFdPropertiesError {}
|
impl Error for MemoryFdPropertiesError {}
|
||||||
|
|
||||||
impl Display for MemoryFdPropertiesError {
|
impl Display for MemoryFdPropertiesError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
|
Self::OutOfHostMemory => write!(f, "no memory available on the host"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -984,7 +974,6 @@ impl Display for MemoryFdPropertiesError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::InvalidExternalHandle => {
|
Self::InvalidExternalHandle => {
|
||||||
write!(f, "the provided external handle was not valid")
|
write!(f, "the provided external handle was not valid")
|
||||||
}
|
}
|
||||||
@ -1000,7 +989,6 @@ impl Display for MemoryFdPropertiesError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for MemoryFdPropertiesError {
|
impl From<VulkanError> for MemoryFdPropertiesError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
VulkanError::OutOfHostMemory => Self::OutOfHostMemory,
|
VulkanError::OutOfHostMemory => Self::OutOfHostMemory,
|
||||||
@ -1011,7 +999,6 @@ impl From<VulkanError> for MemoryFdPropertiesError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for MemoryFdPropertiesError {
|
impl From<RequirementNotMet> for MemoryFdPropertiesError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -42,7 +42,7 @@ use std::{
|
|||||||
|
|
||||||
/// Represents one of the available physical devices on this machine.
|
/// Represents one of the available physical devices on this machine.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use vulkano::{
|
/// # use vulkano::{
|
||||||
@ -465,6 +465,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn directfb_presentation_support_unchecked<D>(
|
pub unsafe fn directfb_presentation_support_unchecked<D>(
|
||||||
&self,
|
&self,
|
||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
@ -481,12 +482,13 @@ impl PhysicalDevice {
|
|||||||
|
|
||||||
/// Retrieves the external memory properties supported for buffers with a given configuration.
|
/// Retrieves the external memory properties supported for buffers with a given configuration.
|
||||||
///
|
///
|
||||||
/// Instance API version must be at least 1.1, or the
|
/// Instance API version must be at least 1.1, or the [`khr_external_memory_capabilities`]
|
||||||
/// [`khr_external_memory_capabilities`](crate::instance::InstanceExtensions::khr_external_memory_capabilities)
|
|
||||||
/// extension must be enabled on the instance.
|
/// extension must be enabled on the instance.
|
||||||
///
|
///
|
||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// do not need to make a call to the Vulkan API again.
|
||||||
|
///
|
||||||
|
/// [`khr_external_memory_capabilities`]: crate::instance::InstanceExtensions::khr_external_memory_capabilities
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn external_buffer_properties(
|
pub fn external_buffer_properties(
|
||||||
&self,
|
&self,
|
||||||
@ -537,6 +539,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn external_buffer_properties_unchecked(
|
pub unsafe fn external_buffer_properties_unchecked(
|
||||||
&self,
|
&self,
|
||||||
info: ExternalBufferInfo,
|
info: ExternalBufferInfo,
|
||||||
@ -592,12 +595,13 @@ impl PhysicalDevice {
|
|||||||
/// Retrieves the external handle properties supported for fences with a given
|
/// Retrieves the external handle properties supported for fences with a given
|
||||||
/// configuration.
|
/// configuration.
|
||||||
///
|
///
|
||||||
/// The instance API version must be at least 1.1, or the
|
/// The instance API version must be at least 1.1, or the [`khr_external_fence_capabilities`]
|
||||||
/// [`khr_external_fence_capabilities`](crate::instance::InstanceExtensions::khr_external_fence_capabilities)
|
|
||||||
/// extension must be enabled on the instance.
|
/// extension must be enabled on the instance.
|
||||||
///
|
///
|
||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// do not need to make a call to the Vulkan API again.
|
||||||
|
///
|
||||||
|
/// [`khr_external_fence_capabilities`]: crate::instance::InstanceExtensions::khr_external_fence_capabilities
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn external_fence_properties(
|
pub fn external_fence_properties(
|
||||||
&self,
|
&self,
|
||||||
@ -640,6 +644,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn external_fence_properties_unchecked(
|
pub unsafe fn external_fence_properties_unchecked(
|
||||||
&self,
|
&self,
|
||||||
info: ExternalFenceInfo,
|
info: ExternalFenceInfo,
|
||||||
@ -699,11 +704,12 @@ impl PhysicalDevice {
|
|||||||
/// configuration.
|
/// configuration.
|
||||||
///
|
///
|
||||||
/// The instance API version must be at least 1.1, or the
|
/// The instance API version must be at least 1.1, or the
|
||||||
/// [`khr_external_semaphore_capabilities`](crate::instance::InstanceExtensions::khr_external_semaphore_capabilities)
|
/// [`khr_external_semaphore_capabilities`] extension must be enabled on the instance.
|
||||||
/// extension must be enabled on the instance.
|
|
||||||
///
|
///
|
||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// do not need to make a call to the Vulkan API again.
|
||||||
|
///
|
||||||
|
/// [`khr_external_semaphore_capabilities`]: crate::instance::InstanceExtensions::khr_external_semaphore_capabilities
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn external_semaphore_properties(
|
pub fn external_semaphore_properties(
|
||||||
&self,
|
&self,
|
||||||
@ -746,6 +752,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn external_semaphore_properties_unchecked(
|
pub unsafe fn external_semaphore_properties_unchecked(
|
||||||
&self,
|
&self,
|
||||||
info: ExternalSemaphoreInfo,
|
info: ExternalSemaphoreInfo,
|
||||||
@ -827,6 +834,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn format_properties_unchecked(&self, format: Format) -> FormatProperties {
|
pub unsafe fn format_properties_unchecked(&self, format: Format) -> FormatProperties {
|
||||||
self.format_properties.get_or_insert(format, |&format| {
|
self.format_properties.get_or_insert(format, |&format| {
|
||||||
let mut format_properties2 = ash::vk::FormatProperties2::default();
|
let mut format_properties2 = ash::vk::FormatProperties2::default();
|
||||||
@ -913,6 +921,7 @@ impl PhysicalDevice {
|
|||||||
unsafe { Ok(self.image_format_properties_unchecked(image_format_info)?) }
|
unsafe { Ok(self.image_format_properties_unchecked(image_format_info)?) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: Shouldn't this be private?
|
||||||
pub fn validate_image_format_properties(
|
pub fn validate_image_format_properties(
|
||||||
&self,
|
&self,
|
||||||
image_format_info: &ImageFormatInfo,
|
image_format_info: &ImageFormatInfo,
|
||||||
@ -1019,6 +1028,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn image_format_properties_unchecked(
|
pub unsafe fn image_format_properties_unchecked(
|
||||||
&self,
|
&self,
|
||||||
mut image_format_info: ImageFormatInfo,
|
mut image_format_info: ImageFormatInfo,
|
||||||
@ -1200,7 +1210,6 @@ impl PhysicalDevice {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `window` must be a valid QNX Screen `_screen_window` handle.
|
/// - `window` must be a valid QNX Screen `_screen_window` handle.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn qnx_screen_presentation_support<W>(
|
pub unsafe fn qnx_screen_presentation_support<W>(
|
||||||
&self,
|
&self,
|
||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
@ -1313,6 +1322,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn sparse_image_format_properties_unchecked(
|
pub unsafe fn sparse_image_format_properties_unchecked(
|
||||||
&self,
|
&self,
|
||||||
format_info: SparseImageFormatInfo,
|
format_info: SparseImageFormatInfo,
|
||||||
@ -1465,10 +1475,9 @@ impl PhysicalDevice {
|
|||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// 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.
|
/// - Panics if the physical device and the surface don't belong to the same instance.
|
||||||
#[inline]
|
|
||||||
pub fn surface_capabilities<W>(
|
pub fn surface_capabilities<W>(
|
||||||
&self,
|
&self,
|
||||||
surface: &Surface<W>,
|
surface: &Surface<W>,
|
||||||
@ -1700,10 +1709,9 @@ impl PhysicalDevice {
|
|||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// 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.
|
/// - Panics if the physical device and the surface don't belong to the same instance.
|
||||||
#[inline]
|
|
||||||
pub fn surface_formats<W>(
|
pub fn surface_formats<W>(
|
||||||
&self,
|
&self,
|
||||||
surface: &Surface<W>,
|
surface: &Surface<W>,
|
||||||
@ -1928,10 +1936,9 @@ impl PhysicalDevice {
|
|||||||
/// The results of this function are cached, so that future calls with the same arguments
|
/// 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.
|
/// 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.
|
/// - Panics if the physical device and the surface don't belong to the same instance.
|
||||||
#[inline]
|
|
||||||
pub fn surface_present_modes<W>(
|
pub fn surface_present_modes<W>(
|
||||||
&self,
|
&self,
|
||||||
surface: &Surface<W>,
|
surface: &Surface<W>,
|
||||||
@ -2116,6 +2123,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn tool_properties_unchecked(&self) -> Result<Vec<ToolProperties>, VulkanError> {
|
pub unsafe fn tool_properties_unchecked(&self) -> Result<Vec<ToolProperties>, VulkanError> {
|
||||||
let fns = self.instance.fns();
|
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
|
/// Queries whether the physical device supports presenting to Wayland surfaces from queues of
|
||||||
/// given queue family.
|
/// the given queue family.
|
||||||
///
|
///
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `display` must be a valid Wayland `wl_display` handle.
|
/// - `display` must be a valid Wayland `wl_display` handle.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn wayland_presentation_support<D>(
|
pub unsafe fn wayland_presentation_support<D>(
|
||||||
&self,
|
&self,
|
||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
@ -2289,6 +2296,7 @@ impl PhysicalDevice {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn win32_presentation_support_unchecked(&self, queue_family_index: u32) -> bool {
|
pub unsafe fn win32_presentation_support_unchecked(&self, queue_family_index: u32) -> bool {
|
||||||
let fns = self.instance.fns();
|
let fns = self.instance.fns();
|
||||||
(fns.khr_win32_surface
|
(fns.khr_win32_surface
|
||||||
@ -2303,7 +2311,6 @@ impl PhysicalDevice {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `connection` must be a valid X11 `xcb_connection_t` handle.
|
/// - `connection` must be a valid X11 `xcb_connection_t` handle.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn xcb_presentation_support<C>(
|
pub unsafe fn xcb_presentation_support<C>(
|
||||||
&self,
|
&self,
|
||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
@ -2368,7 +2375,6 @@ impl PhysicalDevice {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `display` must be a valid Xlib `Display` handle.
|
/// - `display` must be a valid Xlib `Display` handle.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn xlib_presentation_support<D>(
|
pub unsafe fn xlib_presentation_support<D>(
|
||||||
&self,
|
&self,
|
||||||
queue_family_index: u32,
|
queue_family_index: u32,
|
||||||
@ -2447,7 +2453,6 @@ impl PartialEq for PhysicalDevice {
|
|||||||
impl Eq for PhysicalDevice {}
|
impl Eq for PhysicalDevice {}
|
||||||
|
|
||||||
impl Hash for PhysicalDevice {
|
impl Hash for PhysicalDevice {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.instance.hash(state);
|
self.instance.hash(state);
|
||||||
@ -2504,14 +2509,15 @@ impl From<ash::vk::ConformanceVersion> for ConformanceVersion {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ConformanceVersion {
|
impl Debug for ConformanceVersion {
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
|
write!(f, "{}.{}.{}", self.major, self.minor, self.patch)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ConformanceVersion {
|
impl Display for ConformanceVersion {
|
||||||
fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), FmtError> {
|
#[inline]
|
||||||
Debug::fmt(self, formatter)
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
|
Debug::fmt(self, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2716,24 +2722,18 @@ pub enum PhysicalDeviceError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for PhysicalDeviceError {
|
impl Error for PhysicalDeviceError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::VulkanError(ref err) => Some(err),
|
Self::VulkanError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PhysicalDeviceError {
|
impl Display for PhysicalDeviceError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::VulkanError(_) => write!(
|
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
|
||||||
f,
|
|
||||||
"a runtime error occurred",
|
|
||||||
),
|
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -2742,17 +2742,18 @@ impl Display for PhysicalDeviceError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::NotSupported => write!(
|
Self::NotSupported => write!(
|
||||||
f,
|
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 {
|
Self::QueueFamilyIndexOutOfRange {
|
||||||
queue_family_index,
|
queue_family_index,
|
||||||
queue_family_count,
|
queue_family_count,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
queue_family_index, queue_family_count,
|
||||||
),
|
),
|
||||||
Self::SurfaceNotSupported => write!(
|
Self::SurfaceNotSupported => write!(
|
||||||
@ -2764,14 +2765,12 @@ impl Display for PhysicalDeviceError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for PhysicalDeviceError {
|
impl From<VulkanError> for PhysicalDeviceError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
Self::VulkanError(err)
|
Self::VulkanError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for PhysicalDeviceError {
|
impl From<RequirementNotMet> for PhysicalDeviceError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -47,6 +47,7 @@ pub struct Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Queue {
|
impl Queue {
|
||||||
|
// TODO: Make public
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn from_handle(
|
pub(super) fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
@ -110,12 +111,14 @@ unsafe impl VulkanObject for Queue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl DeviceOwned for Queue {
|
unsafe impl DeviceOwned for Queue {
|
||||||
|
#[inline]
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Queue {
|
impl PartialEq for Queue {
|
||||||
|
#[inline]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.id == other.id
|
self.id == other.id
|
||||||
&& self.queue_family_index == other.queue_family_index
|
&& self.queue_family_index == other.queue_family_index
|
||||||
@ -126,7 +129,6 @@ impl PartialEq for Queue {
|
|||||||
impl Eq for Queue {}
|
impl Eq for Queue {}
|
||||||
|
|
||||||
impl Hash for Queue {
|
impl Hash for Queue {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.id.hash(state);
|
self.id.hash(state);
|
||||||
self.queue_family_index.hash(state);
|
self.queue_family_index.hash(state);
|
||||||
@ -158,7 +160,6 @@ impl<'a> QueueGuard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn bind_sparse_unchecked(
|
pub unsafe fn bind_sparse_unchecked(
|
||||||
&mut self,
|
&mut self,
|
||||||
bind_infos: impl IntoIterator<Item = BindSparseInfo>,
|
bind_infos: impl IntoIterator<Item = BindSparseInfo>,
|
||||||
@ -449,15 +450,16 @@ impl<'a> QueueGuard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn present_unchecked(
|
pub unsafe fn present_unchecked(
|
||||||
&mut self,
|
&mut self,
|
||||||
present_info: PresentInfo,
|
present_info: PresentInfo,
|
||||||
) -> impl ExactSizeIterator<Item = Result<bool, VulkanError>> {
|
) -> impl ExactSizeIterator<Item = Result<bool, VulkanError>> {
|
||||||
let &PresentInfo {
|
let PresentInfo {
|
||||||
ref wait_semaphores,
|
ref wait_semaphores,
|
||||||
ref swapchain_infos,
|
ref swapchain_infos,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = &present_info;
|
} = present_info;
|
||||||
|
|
||||||
let wait_semaphores_vk: SmallVec<[_; 4]> = wait_semaphores
|
let wait_semaphores_vk: SmallVec<[_; 4]> = wait_semaphores
|
||||||
.iter()
|
.iter()
|
||||||
@ -573,7 +575,6 @@ impl<'a> QueueGuard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn submit_unchecked(
|
pub unsafe fn submit_unchecked(
|
||||||
&mut self,
|
&mut self,
|
||||||
submit_infos: impl IntoIterator<Item = SubmitInfo>,
|
submit_infos: impl IntoIterator<Item = SubmitInfo>,
|
||||||
@ -842,8 +843,9 @@ impl<'a> QueueGuard<'a> {
|
|||||||
|
|
||||||
/// Opens a queue debug label region.
|
/// Opens a queue debug label region.
|
||||||
///
|
///
|
||||||
/// The [`ext_debug_utils`](crate::instance::InstanceExtensions::ext_debug_utils) must be
|
/// The [`ext_debug_utils`] extension must be enabled on the instance.
|
||||||
/// enabled on the instance.
|
///
|
||||||
|
/// [`ext_debug_utils`]: crate::instance::InstanceExtensions::ext_debug_utils
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn begin_debug_utils_label(
|
pub fn begin_debug_utils_label(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -881,6 +883,7 @@ impl<'a> QueueGuard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn begin_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
|
pub unsafe fn begin_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
|
||||||
let DebugUtilsLabel {
|
let DebugUtilsLabel {
|
||||||
label_name,
|
label_name,
|
||||||
@ -911,8 +914,8 @@ impl<'a> QueueGuard<'a> {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn end_debug_utils_label(&mut self) -> Result<(), QueueError> {
|
pub unsafe fn end_debug_utils_label(&mut self) -> Result<(), QueueError> {
|
||||||
self.validate_end_debug_utils_label()?;
|
self.validate_end_debug_utils_label()?;
|
||||||
|
|
||||||
self.end_debug_utils_label_unchecked();
|
self.end_debug_utils_label_unchecked();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -940,6 +943,7 @@ impl<'a> QueueGuard<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn end_debug_utils_label_unchecked(&mut self) {
|
pub unsafe fn end_debug_utils_label_unchecked(&mut self) {
|
||||||
let fns = self.queue.device.instance().fns();
|
let fns = self.queue.device.instance().fns();
|
||||||
(fns.ext_debug_utils.queue_end_debug_utils_label_ext)(self.queue.handle);
|
(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))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn insert_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
|
pub unsafe fn insert_debug_utils_label_unchecked(&mut self, label_info: DebugUtilsLabel) {
|
||||||
let DebugUtilsLabel {
|
let DebugUtilsLabel {
|
||||||
label_name,
|
label_name,
|
||||||
@ -1106,11 +1111,9 @@ impl Error for QueueError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for QueueError {
|
impl Display for QueueError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::VulkanError(_) => write!(f, "a runtime error occurred",),
|
Self::VulkanError(_) => write!(f, "a runtime error occurred"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1124,14 +1127,12 @@ impl Display for QueueError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for QueueError {
|
impl From<VulkanError> for QueueError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
Self::VulkanError(err)
|
Self::VulkanError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for QueueError {
|
impl From<RequirementNotMet> for QueueError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -50,7 +50,6 @@ pub struct ExtensionRestrictionError {
|
|||||||
impl Error for ExtensionRestrictionError {}
|
impl Error for ExtensionRestrictionError {}
|
||||||
|
|
||||||
impl Display for ExtensionRestrictionError {
|
impl Display for ExtensionRestrictionError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
@ -73,7 +72,6 @@ pub enum ExtensionRestriction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ExtensionRestriction {
|
impl Display for ExtensionRestriction {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match *self {
|
||||||
ExtensionRestriction::NotSupported => {
|
ExtensionRestriction::NotSupported => {
|
||||||
|
@ -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
|
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap46.html#spirvenv-image-formats
|
||||||
impl From<ImageFormat> for Option<Format> {
|
impl From<ImageFormat> for Option<Format> {
|
||||||
|
#[inline]
|
||||||
fn from(val: ImageFormat) -> Self {
|
fn from(val: ImageFormat) -> Self {
|
||||||
match val {
|
match val {
|
||||||
ImageFormat::Unknown => None,
|
ImageFormat::Unknown => None,
|
||||||
@ -252,6 +253,7 @@ pub enum ChromaSampling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ChromaSampling {
|
impl ChromaSampling {
|
||||||
|
#[inline]
|
||||||
pub fn subsampled_extent(&self, mut extent: [u32; 3]) -> [u32; 3] {
|
pub fn subsampled_extent(&self, mut extent: [u32; 3]) -> [u32; 3] {
|
||||||
match self {
|
match self {
|
||||||
ChromaSampling::Mode444 => (),
|
ChromaSampling::Mode444 => (),
|
||||||
|
@ -114,6 +114,7 @@ vulkan_bitflags! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ImageAspects {
|
impl ImageAspects {
|
||||||
|
#[inline]
|
||||||
pub fn iter(&self) -> impl Iterator<Item = ImageAspect> {
|
pub fn iter(&self) -> impl Iterator<Item = ImageAspect> {
|
||||||
let Self {
|
let Self {
|
||||||
color,
|
color,
|
||||||
@ -147,6 +148,7 @@ impl ImageAspects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<ImageAspect> for ImageAspects {
|
impl From<ImageAspect> for ImageAspects {
|
||||||
|
#[inline]
|
||||||
fn from(aspect: ImageAspect) -> Self {
|
fn from(aspect: ImageAspect) -> Self {
|
||||||
let mut result = Self::empty();
|
let mut result = Self::empty();
|
||||||
|
|
||||||
|
@ -548,15 +548,17 @@ impl AttachmentImage {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exports posix file descriptor for the allocated memory
|
/// Exports posix file descriptor for the allocated memory.
|
||||||
/// requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
|
/// Requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
|
||||||
|
#[inline]
|
||||||
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
|
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
|
||||||
self.memory
|
self.memory
|
||||||
.memory()
|
.memory()
|
||||||
.export_fd(ExternalMemoryHandleType::OpaqueFd)
|
.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 {
|
pub fn mem_size(&self) -> DeviceSize {
|
||||||
self.memory.memory().allocation_size()
|
self.memory.memory().allocation_size()
|
||||||
}
|
}
|
||||||
@ -566,7 +568,6 @@ unsafe impl<A> ImageAccess for AttachmentImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
ImageInner {
|
ImageInner {
|
||||||
image: &self.image,
|
image: &self.image,
|
||||||
@ -577,17 +578,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
self.attachment_layout
|
self.attachment_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.attachment_layout
|
self.attachment_layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
Some(ImageDescriptorLayouts {
|
Some(ImageDescriptorLayouts {
|
||||||
storage_image: ImageLayout::General,
|
storage_image: ImageLayout::General,
|
||||||
@ -597,12 +595,10 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
self.initialized.store(true, Ordering::SeqCst);
|
self.initialized.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
self.initialized.load(Ordering::SeqCst)
|
self.initialized.load(Ordering::SeqCst)
|
||||||
}
|
}
|
||||||
@ -618,7 +614,6 @@ unsafe impl<P, A> ImageContent<P> for AttachmentImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn matches_format(&self) -> bool {
|
fn matches_format(&self) -> bool {
|
||||||
true // FIXME:
|
true // FIXME:
|
||||||
}
|
}
|
||||||
@ -628,7 +623,6 @@ impl<A> PartialEq for AttachmentImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -640,7 +634,6 @@ impl<A> Hash for AttachmentImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,6 @@ fn generate_mipmaps<L>(
|
|||||||
|
|
||||||
impl ImmutableImage {
|
impl ImmutableImage {
|
||||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
@ -117,7 +116,6 @@ impl ImmutableImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||||
#[inline]
|
|
||||||
pub fn with_mipmaps(
|
pub fn with_mipmaps(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
@ -149,7 +147,8 @@ impl ImmutableImage {
|
|||||||
|
|
||||||
/// Builds an uninitialized immutable image.
|
/// 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(
|
pub fn uninitialized(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
@ -222,7 +221,6 @@ impl ImmutableImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct an ImmutableImage from the contents of `iter`.
|
/// Construct an ImmutableImage from the contents of `iter`.
|
||||||
#[inline]
|
|
||||||
pub fn from_iter<Px, I>(
|
pub fn from_iter<Px, I>(
|
||||||
iter: I,
|
iter: I,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
@ -318,7 +316,6 @@ unsafe impl<A> ImageAccess for ImmutableImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
ImageInner {
|
ImageInner {
|
||||||
image: &self.image,
|
image: &self.image,
|
||||||
@ -329,22 +326,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
Some(ImageDescriptorLayouts {
|
Some(ImageDescriptorLayouts {
|
||||||
storage_image: ImageLayout::General,
|
storage_image: ImageLayout::General,
|
||||||
@ -359,7 +352,6 @@ unsafe impl<P, A> ImageContent<P> for ImmutableImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn matches_format(&self) -> bool {
|
fn matches_format(&self) -> bool {
|
||||||
true // FIXME:
|
true // FIXME:
|
||||||
}
|
}
|
||||||
@ -369,7 +361,6 @@ impl<A> PartialEq for ImmutableImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -381,7 +372,6 @@ impl<A> Hash for ImmutableImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
@ -402,22 +392,18 @@ unsafe impl<A> ImageAccess for ImmutableImageInitialization<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
self.image.inner()
|
self.image.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
ImageLayout::Undefined
|
ImageLayout::Undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.image.layout
|
self.image.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@ -427,7 +413,6 @@ impl<A> PartialEq for ImmutableImageInitialization<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -439,7 +424,6 @@ impl<A> Hash for ImmutableImageInitialization<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPoolAlloc,
|
A: MemoryPoolAlloc,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
@ -453,7 +437,6 @@ pub enum ImmutableImageCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ImmutableImageCreationError {
|
impl Error for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::ImageCreationError(err) => Some(err),
|
Self::ImageCreationError(err) => Some(err),
|
||||||
@ -464,7 +447,6 @@ impl Error for ImmutableImageCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ImmutableImageCreationError {
|
impl Display for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::ImageCreationError(err) => err.fmt(f),
|
Self::ImageCreationError(err) => err.fmt(f),
|
||||||
@ -475,28 +457,24 @@ impl Display for ImmutableImageCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<ImageCreationError> for ImmutableImageCreationError {
|
impl From<ImageCreationError> for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: ImageCreationError) -> Self {
|
fn from(err: ImageCreationError) -> Self {
|
||||||
Self::ImageCreationError(err)
|
Self::ImageCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DeviceMemoryError> for ImmutableImageCreationError {
|
impl From<DeviceMemoryError> for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DeviceMemoryError) -> Self {
|
fn from(err: DeviceMemoryError) -> Self {
|
||||||
Self::DeviceMemoryAllocationError(err)
|
Self::DeviceMemoryAllocationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for ImmutableImageCreationError {
|
impl From<OomError> for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::DeviceMemoryAllocationError(err.into())
|
Self::DeviceMemoryAllocationError(err.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<CommandBufferBeginError> for ImmutableImageCreationError {
|
impl From<CommandBufferBeginError> for ImmutableImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: CommandBufferBeginError) -> Self {
|
fn from(err: CommandBufferBeginError) -> Self {
|
||||||
Self::CommandBufferBeginError(err)
|
Self::CommandBufferBeginError(err)
|
||||||
}
|
}
|
||||||
|
@ -12,27 +12,28 @@ use crate::{descriptor_set::layout::DescriptorType, macros::vulkan_enum};
|
|||||||
vulkan_enum! {
|
vulkan_enum! {
|
||||||
/// In-memory layout of the pixel data of an image.
|
/// 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*.
|
/// The pixel data of a Vulkan image is arranged in a particular way, which is called its
|
||||||
/// Each image subresource (mipmap level and array layer) in an image can have a different layout,
|
/// *layout*. Each image subresource (mipmap level and array layer) in an image can have a
|
||||||
/// but usually the whole image has its data in the same layout. Layouts are abstract in the sense
|
/// different layout, but usually the whole image has its data in the same layout. Layouts are
|
||||||
/// that the user does not know the specific details of each layout; the device driver is free to
|
/// abstract in the sense that the user does not know the specific details of each layout; the
|
||||||
/// implement each layout in the way it sees fit.
|
/// 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
|
/// The layout of a newly created image is either `Undefined` or `Preinitialized`. Every
|
||||||
/// that can be performed on an image is only possible with specific layouts, so before the
|
/// operation that can be performed on an image is only possible with specific layouts, so
|
||||||
/// operation is performed, the user must perform a *layout transition* on the image. This
|
/// before the operation is performed, the user must perform a *layout transition* on the
|
||||||
/// rearranges the pixel data from one layout into another. Layout transitions are performed as part
|
/// image. This rearranges the pixel data from one layout into another. Layout transitions are
|
||||||
/// of pipeline barriers in a command buffer.
|
/// performed as part of pipeline barriers in a command buffer.
|
||||||
///
|
///
|
||||||
/// The `General` layout is compatible with any operation, so layout transitions are never needed.
|
/// The `General` layout is compatible with any operation, so layout transitions are never
|
||||||
/// However, the other layouts, while more restricted, are usually better optimised for a particular
|
/// needed. However, the other layouts, while more restricted, are usually better optimised for
|
||||||
/// type of operation than `General`, so they are usually preferred.
|
/// 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
|
/// Vulkan does not keep track of layouts itself, so it is the responsibility of the user to
|
||||||
/// track of this information. When performing a layout transition, the previous layout must be
|
/// keep track of this information. When performing a layout transition, the previous layout
|
||||||
/// specified as well. Some operations allow for different layouts, but require the user to specify
|
/// must be specified as well. Some operations allow for different layouts, but require the
|
||||||
/// which one. Vulkano helps with this by providing sensible defaults, automatically tracking the
|
/// user to specify which one. Vulkano helps with this by providing sensible defaults,
|
||||||
/// layout of each image when creating a command buffer, and adding layout transitions where needed.
|
/// automatically tracking the layout of each image when creating a command buffer, and adding
|
||||||
|
/// layout transitions where needed.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
ImageLayout = ImageLayout(i32);
|
ImageLayout = ImageLayout(i32);
|
||||||
|
|
||||||
@ -73,15 +74,15 @@ vulkan_enum! {
|
|||||||
/// tiling, optimal tiling gives undefined results.
|
/// tiling, optimal tiling gives undefined results.
|
||||||
Preinitialized = PREINITIALIZED,
|
Preinitialized = PREINITIALIZED,
|
||||||
|
|
||||||
// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image,
|
/// A combination of `DepthStencilReadOnlyOptimal` for the depth aspect of the image,
|
||||||
// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image.
|
/// and `DepthStencilAttachmentOptimal` for the stencil aspect of the image.
|
||||||
DepthReadOnlyStencilAttachmentOptimal = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL {
|
DepthReadOnlyStencilAttachmentOptimal = DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL {
|
||||||
api_version: V1_1,
|
api_version: V1_1,
|
||||||
device_extensions: [khr_maintenance2],
|
device_extensions: [khr_maintenance2],
|
||||||
},
|
},
|
||||||
|
|
||||||
// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image,
|
/// A combination of `DepthStencilAttachmentOptimal` for the depth aspect of the image,
|
||||||
// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image.
|
/// and `DepthStencilReadOnlyOptimal` for the stencil aspect of the image.
|
||||||
DepthAttachmentStencilReadOnlyOptimal = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL {
|
DepthAttachmentStencilReadOnlyOptimal = DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL {
|
||||||
api_version: V1_1,
|
api_version: V1_1,
|
||||||
device_extensions: [khr_maintenance2],
|
device_extensions: [khr_maintenance2],
|
||||||
|
@ -379,7 +379,7 @@ impl ImageDimensions {
|
|||||||
///
|
///
|
||||||
/// The returned value is always at least 1.
|
/// The returned value is always at least 1.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use vulkano::image::ImageDimensions;
|
/// use vulkano::image::ImageDimensions;
|
||||||
@ -392,7 +392,6 @@ impl ImageDimensions {
|
|||||||
///
|
///
|
||||||
/// assert_eq!(dims.max_mip_levels(), 6);
|
/// assert_eq!(dims.max_mip_levels(), 6);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn max_mip_levels(&self) -> u32 {
|
pub fn max_mip_levels(&self) -> u32 {
|
||||||
// This calculates `log2(max(width, height, depth)) + 1` using fast integer operations.
|
// 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()`.
|
/// Returns `None` if `level` is superior or equal to `max_mip_levels()`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use vulkano::image::ImageDimensions;
|
/// use vulkano::image::ImageDimensions;
|
||||||
@ -443,11 +442,11 @@ impl ImageDimensions {
|
|||||||
/// assert_eq!(dims.mip_level_dimensions(11), None);
|
/// assert_eq!(dims.mip_level_dimensions(11), None);
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
|
||||||
/// In debug mode, Panics if `width`, `height` or `depth` is equal to 0. In release, returns
|
|
||||||
/// an unspecified value.
|
|
||||||
///
|
///
|
||||||
|
/// - 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> {
|
pub fn mip_level_dimensions(&self, level: u32) -> Option<ImageDimensions> {
|
||||||
if level == 0 {
|
if level == 0 {
|
||||||
return Some(*self);
|
return Some(*self);
|
||||||
@ -520,6 +519,7 @@ pub struct ImageSubresourceLayers {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<ImageSubresourceLayers> for ash::vk::ImageSubresourceLayers {
|
impl From<ImageSubresourceLayers> for ash::vk::ImageSubresourceLayers {
|
||||||
|
#[inline]
|
||||||
fn from(val: ImageSubresourceLayers) -> Self {
|
fn from(val: ImageSubresourceLayers) -> Self {
|
||||||
Self {
|
Self {
|
||||||
aspect_mask: val.aspects.into(),
|
aspect_mask: val.aspects.into(),
|
||||||
|
@ -52,7 +52,6 @@ where
|
|||||||
|
|
||||||
impl StorageImage {
|
impl StorageImage {
|
||||||
/// Creates a new image with the given dimensions and format.
|
/// Creates a new image with the given dimensions and format.
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
@ -206,6 +205,7 @@ impl StorageImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Allows the creation of a simple 2D general purpose image view from `StorageImage`.
|
/// Allows the creation of a simple 2D general purpose image view from `StorageImage`.
|
||||||
|
#[inline]
|
||||||
pub fn general_purpose_image_view(
|
pub fn general_purpose_image_view(
|
||||||
queue: Arc<Queue>,
|
queue: Arc<Queue>,
|
||||||
size: [u32; 2],
|
size: [u32; 2],
|
||||||
@ -226,6 +226,7 @@ impl StorageImage {
|
|||||||
flags,
|
flags,
|
||||||
Some(queue.queue_family_index()),
|
Some(queue.queue_family_index()),
|
||||||
);
|
);
|
||||||
|
|
||||||
match image_result {
|
match image_result {
|
||||||
Ok(image) => {
|
Ok(image) => {
|
||||||
let image_view = ImageView::new_default(image);
|
let image_view = ImageView::new_default(image);
|
||||||
@ -238,15 +239,17 @@ impl StorageImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Exports posix file descriptor for the allocated memory
|
/// Exports posix file descriptor for the allocated memory.
|
||||||
/// requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
|
/// Requires `khr_external_memory_fd` and `khr_external_memory` extensions to be loaded.
|
||||||
|
#[inline]
|
||||||
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
|
pub fn export_posix_fd(&self) -> Result<File, DeviceMemoryError> {
|
||||||
self.memory
|
self.memory
|
||||||
.memory()
|
.memory()
|
||||||
.export_fd(ExternalMemoryHandleType::OpaqueFd)
|
.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 {
|
pub fn mem_size(&self) -> DeviceSize {
|
||||||
self.memory.memory().allocation_size()
|
self.memory.memory().allocation_size()
|
||||||
}
|
}
|
||||||
@ -265,7 +268,6 @@ unsafe impl<A> ImageAccess for StorageImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPool,
|
A: MemoryPool,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
ImageInner {
|
ImageInner {
|
||||||
image: &self.image,
|
image: &self.image,
|
||||||
@ -276,17 +278,14 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
ImageLayout::General
|
ImageLayout::General
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
ImageLayout::General
|
ImageLayout::General
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
Some(ImageDescriptorLayouts {
|
Some(ImageDescriptorLayouts {
|
||||||
storage_image: ImageLayout::General,
|
storage_image: ImageLayout::General,
|
||||||
@ -301,7 +300,6 @@ unsafe impl<P, A> ImageContent<P> for StorageImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPool,
|
A: MemoryPool,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn matches_format(&self) -> bool {
|
fn matches_format(&self) -> bool {
|
||||||
true // FIXME:
|
true // FIXME:
|
||||||
}
|
}
|
||||||
@ -311,7 +309,6 @@ impl<A> PartialEq for StorageImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPool,
|
A: MemoryPool,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -323,7 +320,6 @@ impl<A> Hash for StorageImage<A>
|
|||||||
where
|
where
|
||||||
A: MemoryPool,
|
A: MemoryPool,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
|
@ -55,22 +55,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the swapchain this image belongs to.
|
/// Returns the swapchain this image belongs to.
|
||||||
#[inline]
|
|
||||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||||
&self.swapchain
|
&self.swapchain
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn my_image(&self) -> ImageInner<'_> {
|
fn my_image(&self) -> ImageInner<'_> {
|
||||||
self.swapchain.raw_image(self.image_index).unwrap()
|
self.swapchain.raw_image(self.image_index).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn layout_initialized(&self) {
|
fn layout_initialized(&self) {
|
||||||
self.swapchain.image_layout_initialized(self.image_index);
|
self.swapchain.image_layout_initialized(self.image_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
self.swapchain.is_image_layout_initialized(self.image_index)
|
self.swapchain.is_image_layout_initialized(self.image_index)
|
||||||
}
|
}
|
||||||
@ -86,22 +82,18 @@ unsafe impl<W> ImageAccess for SwapchainImage<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
self.my_image()
|
self.my_image()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
ImageLayout::PresentSrc
|
ImageLayout::PresentSrc
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
ImageLayout::PresentSrc
|
ImageLayout::PresentSrc
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
Some(ImageDescriptorLayouts {
|
Some(ImageDescriptorLayouts {
|
||||||
storage_image: ImageLayout::General,
|
storage_image: ImageLayout::General,
|
||||||
@ -111,12 +103,10 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
self.layout_initialized();
|
self.layout_initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
self.is_layout_initialized()
|
self.is_layout_initialized()
|
||||||
}
|
}
|
||||||
@ -126,7 +116,6 @@ unsafe impl<P, W> ImageContent<P> for SwapchainImage<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn matches_format(&self) -> bool {
|
fn matches_format(&self) -> bool {
|
||||||
true // FIXME:
|
true // FIXME:
|
||||||
}
|
}
|
||||||
@ -136,7 +125,6 @@ impl<W> PartialEq for SwapchainImage<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -148,7 +136,6 @@ impl<W> Hash for SwapchainImage<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
|
@ -802,6 +802,7 @@ impl UnsafeImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn new_unchecked(
|
pub unsafe fn new_unchecked(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
create_info: UnsafeImageCreateInfo,
|
create_info: UnsafeImageCreateInfo,
|
||||||
@ -932,6 +933,7 @@ impl UnsafeImage {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::Image,
|
handle: ash::vk::Image,
|
||||||
@ -1079,6 +1081,7 @@ impl UnsafeImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the memory requirements for this image.
|
/// Returns the memory requirements for this image.
|
||||||
|
#[inline]
|
||||||
pub fn memory_requirements(&self) -> MemoryRequirements {
|
pub fn memory_requirements(&self) -> MemoryRequirements {
|
||||||
let image_memory_requirements_info2 = ash::vk::ImageMemoryRequirementsInfo2 {
|
let image_memory_requirements_info2 = ash::vk::ImageMemoryRequirementsInfo2 {
|
||||||
image: self.handle,
|
image: self.handle,
|
||||||
@ -1139,6 +1142,7 @@ impl UnsafeImage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the sparse memory requirements for this image.
|
/// Returns the sparse memory requirements for this image.
|
||||||
|
#[inline]
|
||||||
pub fn sparse_memory_requirements(&self) -> Vec<SparseImageMemoryRequirements> {
|
pub fn sparse_memory_requirements(&self) -> Vec<SparseImageMemoryRequirements> {
|
||||||
let device = &self.device;
|
let device = &self.device;
|
||||||
|
|
||||||
@ -1317,6 +1321,7 @@ impl UnsafeImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub unsafe fn bind_memory(
|
pub unsafe fn bind_memory(
|
||||||
&self,
|
&self,
|
||||||
memory: &DeviceMemory,
|
memory: &DeviceMemory,
|
||||||
@ -1347,10 +1352,10 @@ impl UnsafeImage {
|
|||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn range_size(&self) -> DeviceSize {
|
pub(crate) fn range_size(&self) -> DeviceSize {
|
||||||
self.range_size
|
self.range_size
|
||||||
}
|
}
|
||||||
@ -1360,7 +1365,6 @@ impl UnsafeImage {
|
|||||||
/// In ranges, the subresources are "flattened" to `DeviceSize`, where each index in the range
|
/// 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,
|
/// 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.
|
/// with the mip levels in that aspect, and the array layers in that mip level.
|
||||||
#[inline]
|
|
||||||
pub(crate) fn iter_ranges(
|
pub(crate) fn iter_ranges(
|
||||||
&self,
|
&self,
|
||||||
subresource_range: ImageSubresourceRange,
|
subresource_range: ImageSubresourceRange,
|
||||||
@ -1383,7 +1387,6 @@ impl UnsafeImage {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn range_to_subresources(
|
pub(crate) fn range_to_subresources(
|
||||||
&self,
|
&self,
|
||||||
mut range: Range<DeviceSize>,
|
mut range: Range<DeviceSize>,
|
||||||
@ -1450,7 +1453,6 @@ impl UnsafeImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn state(&self) -> MutexGuard<'_, ImageState> {
|
pub(crate) fn state(&self) -> MutexGuard<'_, ImageState> {
|
||||||
self.state.lock()
|
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
|
/// 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.
|
/// you can easily calculate the position of any layer.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the mipmap level is out of range.
|
/// - 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.
|
/// 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.
|
/// - 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.
|
/// 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.
|
/// - 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
|
/// Same as `color_linear_layout`, except that it retrieves layout for the requested YCbCr
|
||||||
/// component too if the format is a YCbCr format.
|
/// component too if the format is a YCbCr format.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if plane aspect is out of range.
|
/// - Panics if plane aspect is out of range.
|
||||||
/// - Panics if the aspect is not a color or planar aspect.
|
/// - 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 {
|
unsafe impl DeviceOwned for UnsafeImage {
|
||||||
|
#[inline]
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
@ -1739,7 +1742,6 @@ impl PartialEq for UnsafeImage {
|
|||||||
impl Eq for UnsafeImage {}
|
impl Eq for UnsafeImage {}
|
||||||
|
|
||||||
impl Hash for UnsafeImage {
|
impl Hash for UnsafeImage {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -1851,6 +1853,7 @@ pub struct UnsafeImageCreateInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for UnsafeImageCreateInfo {
|
impl Default for UnsafeImageCreateInfo {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
dimensions: ImageDimensions::Dim2d {
|
dimensions: ImageDimensions::Dim2d {
|
||||||
@ -1997,21 +2000,18 @@ pub enum ImageCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ImageCreationError {
|
impl Error for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
ImageCreationError::AllocError(ref err) => Some(err),
|
ImageCreationError::AllocError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ImageCreationError {
|
impl Display for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::AllocError(_) => write!(f, "allocating memory failed"),
|
Self::AllocError(_) => write!(f, "allocating memory failed"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -2020,139 +2020,133 @@ impl Display for ImageCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::Array2dCompatibleNot3d => write!(
|
||||||
Self::Array2dCompatibleNot3d => {
|
f,
|
||||||
write!(
|
"the array_2d_compatible flag was enabled, but the image type was not 3D",
|
||||||
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 \
|
||||||
Self::BlockTexelViewCompatibleNotCompressed => {
|
compressed",
|
||||||
write!(f, "the block_texel_view_compatible flag was enabled, but the given format was not compressed")
|
),
|
||||||
}
|
Self::CubeCompatibleNot2d => write!(
|
||||||
Self::CubeCompatibleNot2d => {
|
f,
|
||||||
write!(
|
"the cube_compatible flag was enabled, but the image type was not 2D",
|
||||||
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 \
|
||||||
Self::CubeCompatibleNotEnoughArrayLayers => {
|
than 6",
|
||||||
write!(f, "the cube_compatible flag was enabled, but the number of array layers was less than 6")
|
),
|
||||||
}
|
Self::CubeCompatibleNotSquare => write!(
|
||||||
Self::CubeCompatibleNotSquare => {
|
f,
|
||||||
write!(f, "the cube_compatible flag was enabled, but the image dimensions were not square")
|
"the cube_compatible flag was enabled, but the image dimensions were not square",
|
||||||
}
|
),
|
||||||
Self::CubeCompatibleMultisampling => {
|
Self::CubeCompatibleMultisampling => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"the cube_compatible flag was enabled together with multisampling",
|
||||||
"the cube_compatible flag was enabled together with multisampling"
|
),
|
||||||
)
|
Self::ExternalMemoryInvalidInitialLayout => write!(
|
||||||
}
|
f,
|
||||||
Self::ExternalMemoryInvalidInitialLayout => {
|
"one or more external memory handle types were provided, but the initial layout \
|
||||||
write!(f, "one or more external memory handle types were provided, but the initial layout was not `Undefined`")
|
was not `Undefined`",
|
||||||
}
|
),
|
||||||
Self::FormatNotSupported => {
|
Self::FormatNotSupported => {
|
||||||
write!(f, "the given format was not supported by the device")
|
write!(f, "the given format was not supported by the device")
|
||||||
}
|
}
|
||||||
Self::FormatUsageNotSupported { .. } => {
|
Self::FormatUsageNotSupported { .. } => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"a requested usage flag was not supported by the given format",
|
||||||
"a requested usage flag was not supported by the given format"
|
),
|
||||||
)
|
Self::ImageFormatPropertiesNotSupported => write!(
|
||||||
}
|
f,
|
||||||
Self::ImageFormatPropertiesNotSupported => {
|
"the image configuration as queried through the `image_format_properties` function \
|
||||||
write!(f, "the image configuration as queried through the `image_format_properties` function was not supported by the device")
|
was not supported by the device",
|
||||||
}
|
),
|
||||||
Self::MaxArrayLayersExceeded { .. } => {
|
Self::MaxArrayLayersExceeded { .. } => write!(
|
||||||
write!(f, "the number of array layers exceeds the maximum supported by the device for this image configuration")
|
f,
|
||||||
}
|
"the number of array layers exceeds the maximum supported by the device for this \
|
||||||
Self::MaxDimensionsExceeded { .. } => {
|
image configuration",
|
||||||
write!(f, "the specified dimensions exceed the maximum supported by the device for this image configuration")
|
),
|
||||||
}
|
Self::MaxDimensionsExceeded { .. } => write!(
|
||||||
Self::MaxFramebufferDimensionsExceeded { .. } => {
|
f,
|
||||||
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")
|
"the specified dimensions exceed the maximum supported by the device for this \
|
||||||
}
|
image configuration",
|
||||||
Self::MaxMipLevelsExceeded { .. } => {
|
),
|
||||||
write!(
|
Self::MaxFramebufferDimensionsExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the maximum number of mip levels for the given dimensions has been exceeded"
|
"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::MultisampleCubeCompatible => {
|
Self::MaxMipLevelsExceeded { .. } => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"the maximum number of mip levels for the given dimensions has been exceeded",
|
||||||
"multisampling was enabled, and the `cube_compatible` flag was set"
|
),
|
||||||
)
|
Self::MultisampleCubeCompatible => write!(
|
||||||
}
|
f,
|
||||||
|
"multisampling was enabled, and the `cube_compatible` flag was set",
|
||||||
|
),
|
||||||
Self::MultisampleLinearTiling => {
|
Self::MultisampleLinearTiling => {
|
||||||
write!(f, "multisampling was enabled, and tiling was `Linear`")
|
write!(f, "multisampling was enabled, and tiling was `Linear`")
|
||||||
}
|
}
|
||||||
Self::MultisampleMultipleMipLevels => {
|
Self::MultisampleMultipleMipLevels => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"multisampling was enabled, and multiple mip levels were specified",
|
||||||
"multisampling was enabled, and multiple mip levels were specified"
|
),
|
||||||
)
|
Self::MultisampleNot2d => write!(
|
||||||
}
|
f,
|
||||||
Self::MultisampleNot2d => {
|
"multisampling was enabled, but the image type was not 2D",
|
||||||
write!(
|
),
|
||||||
f,
|
Self::SampleCountNotSupported { .. } => write!(
|
||||||
"multisampling was enabled, but the image type was not 2D"
|
f,
|
||||||
)
|
"the sample count is not supported by the device for this image configuration",
|
||||||
}
|
),
|
||||||
Self::SampleCountNotSupported { .. } => {
|
Self::SharingQueueFamilyIndexOutOfRange { .. } => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"the sharing mode was set to `Concurrent`, but one of the specified queue family \
|
||||||
"the sample count is not supported by the device for this image configuration"
|
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")
|
|
||||||
}
|
|
||||||
Self::StencilUsageMismatch {
|
Self::StencilUsageMismatch {
|
||||||
usage: _,
|
usage: _,
|
||||||
stencil_usage: _,
|
stencil_usage: _,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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 => {
|
Self::YcbcrFormatMultisampling => {
|
||||||
write!(f, "a YCbCr format was given, and multisampling was enabled")
|
write!(f, "a YCbCr format was given, and multisampling was enabled")
|
||||||
}
|
}
|
||||||
Self::YcbcrFormatNot2d => {
|
Self::YcbcrFormatNot2d => {
|
||||||
write!(f, "a YCbCr format was given, but the image type was not 2D")
|
write!(f, "a YCbCr format was given, but the image type was not 2D")
|
||||||
}
|
}
|
||||||
Self::DirectImageViewCreationFailed(e) => {
|
Self::DirectImageViewCreationFailed(e) => write!(f, "Image view creation failed {}", e),
|
||||||
write!(f, "Image view creation failed {}", e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for ImageCreationError {
|
impl From<OomError> for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::AllocError(DeviceMemoryError::OomError(err))
|
Self::AllocError(DeviceMemoryError::OomError(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DeviceMemoryError> for ImageCreationError {
|
impl From<DeviceMemoryError> for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DeviceMemoryError) -> Self {
|
fn from(err: DeviceMemoryError) -> Self {
|
||||||
Self::AllocError(err)
|
Self::AllocError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for ImageCreationError {
|
impl From<VulkanError> for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::AllocError(err.into()),
|
err @ VulkanError::OutOfHostMemory => Self::AllocError(err.into()),
|
||||||
@ -2163,7 +2157,6 @@ impl From<VulkanError> for ImageCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for ImageCreationError {
|
impl From<RequirementNotMet> for ImageCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -247,7 +247,6 @@ impl PartialEq for dyn ImageAccess {
|
|||||||
impl Eq for dyn ImageAccess {}
|
impl Eq for dyn ImageAccess {}
|
||||||
|
|
||||||
impl Hash for dyn ImageAccess {
|
impl Hash for dyn ImageAccess {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
@ -274,12 +273,10 @@ unsafe impl<I> ImageAccess for ImageAccessFromUndefinedLayout<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess,
|
I: ImageAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
self.image.inner()
|
self.image.inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
if self.preinitialized {
|
if self.preinitialized {
|
||||||
ImageLayout::Preinitialized
|
ImageLayout::Preinitialized
|
||||||
@ -288,12 +285,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
self.image.final_layout_requirement()
|
self.image.final_layout_requirement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
self.image.descriptor_layouts()
|
self.image.descriptor_layouts()
|
||||||
}
|
}
|
||||||
@ -303,7 +298,6 @@ impl<I> PartialEq for ImageAccessFromUndefinedLayout<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess,
|
I: ImageAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.inner() == other.inner()
|
self.inner() == other.inner()
|
||||||
}
|
}
|
||||||
@ -315,7 +309,6 @@ impl<I> Hash for ImageAccessFromUndefinedLayout<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess,
|
I: ImageAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.inner().hash(state);
|
self.inner().hash(state);
|
||||||
}
|
}
|
||||||
@ -331,32 +324,26 @@ where
|
|||||||
T: SafeDeref + Send + Sync,
|
T: SafeDeref + Send + Sync,
|
||||||
T::Target: ImageAccess,
|
T::Target: ImageAccess,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn inner(&self) -> ImageInner<'_> {
|
fn inner(&self) -> ImageInner<'_> {
|
||||||
(**self).inner()
|
(**self).inner()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn initial_layout_requirement(&self) -> ImageLayout {
|
fn initial_layout_requirement(&self) -> ImageLayout {
|
||||||
(**self).initial_layout_requirement()
|
(**self).initial_layout_requirement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn final_layout_requirement(&self) -> ImageLayout {
|
fn final_layout_requirement(&self) -> ImageLayout {
|
||||||
(**self).final_layout_requirement()
|
(**self).final_layout_requirement()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
fn descriptor_layouts(&self) -> Option<ImageDescriptorLayouts> {
|
||||||
(**self).descriptor_layouts()
|
(**self).descriptor_layouts()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn layout_initialized(&self) {
|
unsafe fn layout_initialized(&self) {
|
||||||
(**self).layout_initialized();
|
(**self).layout_initialized();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn is_layout_initialized(&self) -> bool {
|
fn is_layout_initialized(&self) -> bool {
|
||||||
(**self).is_layout_initialized()
|
(**self).is_layout_initialized()
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,6 @@ where
|
|||||||
/// `stencil`, `plane0`, `plane1` or `plane2`.
|
/// `stencil`, `plane0`, `plane1` or `plane2`.
|
||||||
/// - Panics if `create_info.aspects` contains more more than one aspect, unless `depth` and
|
/// - Panics if `create_info.aspects` contains more more than one aspect, unless `depth` and
|
||||||
/// `stencil` are the only aspects selected.
|
/// `stencil` are the only aspects selected.
|
||||||
#[inline]
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
image: Arc<I>,
|
image: Arc<I>,
|
||||||
create_info: ImageViewCreateInfo,
|
create_info: ImageViewCreateInfo,
|
||||||
@ -468,7 +467,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn new_unchecked(
|
pub unsafe fn new_unchecked(
|
||||||
image: Arc<I>,
|
image: Arc<I>,
|
||||||
create_info: ImageViewCreateInfo,
|
create_info: ImageViewCreateInfo,
|
||||||
@ -557,7 +555,6 @@ where
|
|||||||
|
|
||||||
/// Creates a default `ImageView`. Equivalent to
|
/// Creates a default `ImageView`. Equivalent to
|
||||||
/// `ImageView::new(image, ImageViewCreateInfo::from_image(image))`.
|
/// `ImageView::new(image, ImageViewCreateInfo::from_image(image))`.
|
||||||
#[inline]
|
|
||||||
pub fn new_default(image: Arc<I>) -> Result<Arc<ImageView<I>>, ImageViewCreationError> {
|
pub fn new_default(image: Arc<I>) -> Result<Arc<ImageView<I>>, ImageViewCreationError> {
|
||||||
let create_info = ImageViewCreateInfo::from_image(&image);
|
let create_info = ImageViewCreateInfo::from_image(&image);
|
||||||
Self::new(image, create_info)
|
Self::new(image, create_info)
|
||||||
@ -569,7 +566,6 @@ where
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `image`.
|
/// - `handle` must be a valid Vulkan object handle created from `image`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
image: Arc<I>,
|
image: Arc<I>,
|
||||||
handle: ash::vk::ImageView,
|
handle: ash::vk::ImageView,
|
||||||
@ -653,7 +649,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkImageViewCreateInfo.html#_description
|
// 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 {
|
fn get_default_usage(aspects: ImageAspects, image: &UnsafeImage) -> ImageUsage {
|
||||||
let has_stencil_aspect = aspects.stencil;
|
let has_stencil_aspect = aspects.stencil;
|
||||||
let has_non_stencil_aspect = !(ImageAspects {
|
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
|
// 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 {
|
unsafe fn get_format_features(format: Format, image: &UnsafeImage) -> FormatFeatures {
|
||||||
let device = image.device();
|
let device = image.device();
|
||||||
|
|
||||||
@ -712,7 +706,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the wrapped image that this image view was created from.
|
/// Returns the wrapped image that this image view was created from.
|
||||||
#[inline]
|
|
||||||
pub fn image(&self) -> &Arc<I> {
|
pub fn image(&self) -> &Arc<I> {
|
||||||
&self.image
|
&self.image
|
||||||
}
|
}
|
||||||
@ -722,7 +715,6 @@ impl<I> Drop for ImageView<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess + ?Sized,
|
I: ImageAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let device = self.device();
|
let device = self.device();
|
||||||
@ -738,7 +730,6 @@ where
|
|||||||
{
|
{
|
||||||
type Object = ash::vk::ImageView;
|
type Object = ash::vk::ImageView;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn internal_object(&self) -> ash::vk::ImageView {
|
fn internal_object(&self) -> ash::vk::ImageView {
|
||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
@ -748,7 +739,6 @@ unsafe impl<I> DeviceOwned for ImageView<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess + ?Sized,
|
I: ImageAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.image.inner().image.device()
|
self.image.inner().image.device()
|
||||||
}
|
}
|
||||||
@ -758,7 +748,6 @@ impl<I> PartialEq for ImageView<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess + ?Sized,
|
I: ImageAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.device() == other.device()
|
self.handle == other.handle && self.device() == other.device()
|
||||||
}
|
}
|
||||||
@ -770,7 +759,6 @@ impl<I> Hash for ImageView<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess + ?Sized,
|
I: ImageAccess + ?Sized,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -981,24 +969,18 @@ pub enum ImageViewCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ImageViewCreationError {
|
impl Error for ImageViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
ImageViewCreationError::OomError(ref err) => Some(err),
|
ImageViewCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ImageViewCreationError {
|
impl Display for ImageViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(
|
Self::OomError(_) => write!(f, "allocating memory failed",),
|
||||||
f,
|
|
||||||
"allocating memory failed",
|
|
||||||
),
|
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1007,10 +989,10 @@ impl Display for ImageViewCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::Array2dCompatibleMultipleMipLevels => write!(
|
Self::Array2dCompatibleMultipleMipLevels => write!(
|
||||||
f,
|
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!(
|
Self::ArrayLayersOutOfRange { .. } => write!(
|
||||||
f,
|
f,
|
||||||
@ -1018,35 +1000,37 @@ impl Display for ImageViewCreationError {
|
|||||||
),
|
),
|
||||||
Self::BlockTexelViewCompatibleMultipleArrayLayers => write!(
|
Self::BlockTexelViewCompatibleMultipleArrayLayers => write!(
|
||||||
f,
|
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!(
|
Self::BlockTexelViewCompatibleMultipleMipLevels => write!(
|
||||||
f,
|
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!(
|
Self::BlockTexelViewCompatibleUncompressedIs3d => write!(
|
||||||
f,
|
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!(
|
Self::FormatChromaSubsamplingInvalidImageDimensions => write!(
|
||||||
f,
|
f,
|
||||||
"the requested format has chroma subsampling, but the width and/or height of the image was not a multiple of 2",
|
"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::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!(
|
Self::FormatRequiresSamplerYcbcrConversion { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the format requires a sampler YCbCr conversion, but none was provided",
|
"the format requires a sampler YCbCr conversion, but none was provided",
|
||||||
),
|
),
|
||||||
Self::FormatUsageNotSupported { .. } => write!(
|
Self::FormatUsageNotSupported { .. } => write!(
|
||||||
f,
|
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!(
|
Self::ImageAspectsNotCompatible { .. } => write!(
|
||||||
f,
|
f,
|
||||||
@ -1058,11 +1042,13 @@ impl Display for ImageViewCreationError {
|
|||||||
),
|
),
|
||||||
Self::ImageNotArray2dCompatible => write!(
|
Self::ImageNotArray2dCompatible => write!(
|
||||||
f,
|
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!(
|
Self::ImageNotCubeCompatible => write!(
|
||||||
f,
|
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!(
|
Self::ImageTypeNotCompatible => write!(
|
||||||
f,
|
f,
|
||||||
@ -1078,23 +1064,28 @@ impl Display for ImageViewCreationError {
|
|||||||
),
|
),
|
||||||
Self::MultisamplingNot2d => write!(
|
Self::MultisamplingNot2d => write!(
|
||||||
f,
|
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!(
|
Self::SamplerYcbcrConversionComponentMappingNotIdentity { .. } => write!(
|
||||||
f,
|
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!(
|
Self::TypeCubeArrayNotMultipleOf6ArrayLayers => write!(
|
||||||
f,
|
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!(
|
Self::TypeCubeNot6ArrayLayers => write!(
|
||||||
f,
|
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!(
|
Self::TypeNonArrayedMultipleArrayLayers => write!(
|
||||||
f,
|
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 {
|
Self::UsageNotSupportedByImage {
|
||||||
usage: _,
|
usage: _,
|
||||||
@ -1108,14 +1099,12 @@ impl Display for ImageViewCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for ImageViewCreationError {
|
impl From<OomError> for ImageViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> ImageViewCreationError {
|
fn from(err: OomError) -> ImageViewCreationError {
|
||||||
ImageViewCreationError::OomError(err)
|
ImageViewCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for ImageViewCreationError {
|
impl From<VulkanError> for ImageViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> ImageViewCreationError {
|
fn from(err: VulkanError) -> ImageViewCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => OomError::from(err).into(),
|
err @ VulkanError::OutOfHostMemory => OomError::from(err).into(),
|
||||||
@ -1126,7 +1115,6 @@ impl From<VulkanError> for ImageViewCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for ImageViewCreationError {
|
impl From<RequirementNotMet> for ImageViewCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -1202,6 +1190,7 @@ pub unsafe trait ImageViewAbstract:
|
|||||||
fn component_mapping(&self) -> ComponentMapping;
|
fn component_mapping(&self) -> ComponentMapping;
|
||||||
|
|
||||||
/// Returns the dimensions of this view.
|
/// Returns the dimensions of this view.
|
||||||
|
#[inline]
|
||||||
fn dimensions(&self) -> ImageDimensions {
|
fn dimensions(&self) -> ImageDimensions {
|
||||||
let subresource_range = self.subresource_range();
|
let subresource_range = self.subresource_range();
|
||||||
let array_layers =
|
let array_layers =
|
||||||
@ -1262,52 +1251,42 @@ unsafe impl<I> ImageViewAbstract for ImageView<I>
|
|||||||
where
|
where
|
||||||
I: ImageAccess + Debug + 'static,
|
I: ImageAccess + Debug + 'static,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn image(&self) -> Arc<dyn ImageAccess> {
|
fn image(&self) -> Arc<dyn ImageAccess> {
|
||||||
self.image.clone()
|
self.image.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn component_mapping(&self) -> ComponentMapping {
|
fn component_mapping(&self) -> ComponentMapping {
|
||||||
self.component_mapping
|
self.component_mapping
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn filter_cubic(&self) -> bool {
|
fn filter_cubic(&self) -> bool {
|
||||||
self.filter_cubic
|
self.filter_cubic
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn filter_cubic_minmax(&self) -> bool {
|
fn filter_cubic_minmax(&self) -> bool {
|
||||||
self.filter_cubic_minmax
|
self.filter_cubic_minmax
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn format(&self) -> Option<Format> {
|
fn format(&self) -> Option<Format> {
|
||||||
self.format
|
self.format
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn format_features(&self) -> &FormatFeatures {
|
fn format_features(&self) -> &FormatFeatures {
|
||||||
&self.format_features
|
&self.format_features
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn sampler_ycbcr_conversion(&self) -> Option<&Arc<SamplerYcbcrConversion>> {
|
fn sampler_ycbcr_conversion(&self) -> Option<&Arc<SamplerYcbcrConversion>> {
|
||||||
self.sampler_ycbcr_conversion.as_ref()
|
self.sampler_ycbcr_conversion.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn subresource_range(&self) -> &ImageSubresourceRange {
|
fn subresource_range(&self) -> &ImageSubresourceRange {
|
||||||
&self.subresource_range
|
&self.subresource_range
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn usage(&self) -> &ImageUsage {
|
fn usage(&self) -> &ImageUsage {
|
||||||
&self.usage
|
&self.usage
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn view_type(&self) -> ImageViewType {
|
fn view_type(&self) -> ImageViewType {
|
||||||
self.view_type
|
self.view_type
|
||||||
}
|
}
|
||||||
@ -1375,7 +1354,6 @@ impl PartialEq for dyn ImageViewAbstract {
|
|||||||
impl Eq for dyn ImageViewAbstract {}
|
impl Eq for dyn ImageViewAbstract {}
|
||||||
|
|
||||||
impl Hash for dyn ImageViewAbstract {
|
impl Hash for dyn ImageViewAbstract {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.internal_object().hash(state);
|
self.internal_object().hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! Note that the vulkano library can also emit messages to warn you about performance issues.
|
//! 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
|
//! TODO: ^ that's not the case yet, need to choose whether we keep this idea
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! ```
|
//! ```
|
||||||
//! # use vulkano::instance::Instance;
|
//! # 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
|
//! 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
|
//! 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.
|
//! variable, it will be immediately destroyed and your callback will not work.
|
||||||
//!
|
|
||||||
|
|
||||||
use super::Instance;
|
use super::Instance;
|
||||||
use crate::{macros::vulkan_bitflags, RequirementNotMet, RequiresOneOf, VulkanError, VulkanObject};
|
use crate::{macros::vulkan_bitflags, RequirementNotMet, RequiresOneOf, VulkanError, VulkanObject};
|
||||||
@ -254,7 +253,6 @@ pub enum DebugUtilsMessengerCreationError {
|
|||||||
impl Error for DebugUtilsMessengerCreationError {}
|
impl Error for DebugUtilsMessengerCreationError {}
|
||||||
|
|
||||||
impl Display for DebugUtilsMessengerCreationError {
|
impl Display for DebugUtilsMessengerCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
@ -270,14 +268,12 @@ impl Display for DebugUtilsMessengerCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for DebugUtilsMessengerCreationError {
|
impl From<VulkanError> for DebugUtilsMessengerCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> DebugUtilsMessengerCreationError {
|
fn from(err: VulkanError) -> DebugUtilsMessengerCreationError {
|
||||||
panic!("unexpected error: {:?}", err)
|
panic!("unexpected error: {:?}", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for DebugUtilsMessengerCreationError {
|
impl From<RequirementNotMet> for DebugUtilsMessengerCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -22,7 +22,7 @@ impl LayerProperties {
|
|||||||
/// If you want to enable this layer on an instance, you need to pass this value to
|
/// If you want to enable this layer on an instance, you need to pass this value to
|
||||||
/// `Instance::new`.
|
/// `Instance::new`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano::VulkanLibrary;
|
/// use vulkano::VulkanLibrary;
|
||||||
@ -46,7 +46,7 @@ impl LayerProperties {
|
|||||||
///
|
///
|
||||||
/// This description is chosen by the layer itself.
|
/// This description is chosen by the layer itself.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano::VulkanLibrary;
|
/// use vulkano::VulkanLibrary;
|
||||||
@ -68,7 +68,7 @@ impl LayerProperties {
|
|||||||
|
|
||||||
/// Returns the version of Vulkan supported by this layer.
|
/// Returns the version of Vulkan supported by this layer.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano::{Version, VulkanLibrary};
|
/// 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.
|
/// The number is chosen by the layer itself. It can be used for bug reports for example.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano::VulkanLibrary;
|
/// use vulkano::VulkanLibrary;
|
||||||
|
@ -202,7 +202,7 @@ mod layers;
|
|||||||
/// > `export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_api_dump` on Linux if you installed the Vulkan SDK
|
/// > `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.
|
/// > will print the list of raw Vulkan function calls.
|
||||||
///
|
///
|
||||||
/// ## Example
|
/// ## Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use std::{sync::Arc, error::Error};
|
/// # use std::{sync::Arc, error::Error};
|
||||||
@ -506,7 +506,7 @@ impl Instance {
|
|||||||
|
|
||||||
/// Returns an iterator that enumerates the physical devices available.
|
/// Returns an iterator that enumerates the physical devices available.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// # use vulkano::{
|
/// # use vulkano::{
|
||||||
@ -589,7 +589,6 @@ impl PartialEq for Instance {
|
|||||||
impl Eq for Instance {}
|
impl Eq for Instance {}
|
||||||
|
|
||||||
impl Hash for Instance {
|
impl Hash for Instance {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
}
|
}
|
||||||
@ -745,17 +744,15 @@ pub enum InstanceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for InstanceCreationError {
|
impl Error for InstanceCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for InstanceCreationError {
|
impl Display for InstanceCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
@ -764,7 +761,6 @@ impl Display for InstanceCreationError {
|
|||||||
Self::ExtensionNotPresent => write!(f, "extension not present"),
|
Self::ExtensionNotPresent => write!(f, "extension not present"),
|
||||||
Self::IncompatibleDriver => write!(f, "incompatible driver"),
|
Self::IncompatibleDriver => write!(f, "incompatible driver"),
|
||||||
Self::ExtensionRestrictionNotMet(err) => Display::fmt(err, f),
|
Self::ExtensionRestrictionNotMet(err) => Display::fmt(err, f),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -778,21 +774,18 @@ impl Display for InstanceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for InstanceCreationError {
|
impl From<OomError> for InstanceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExtensionRestrictionError> for InstanceCreationError {
|
impl From<ExtensionRestrictionError> for InstanceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: ExtensionRestrictionError) -> Self {
|
fn from(err: ExtensionRestrictionError) -> Self {
|
||||||
Self::ExtensionRestrictionNotMet(err)
|
Self::ExtensionRestrictionNotMet(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for InstanceCreationError {
|
impl From<VulkanError> for InstanceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
|
@ -151,12 +151,11 @@ pub enum OomError {
|
|||||||
impl Error for OomError {}
|
impl Error for OomError {}
|
||||||
|
|
||||||
impl Display for OomError {
|
impl Display for OomError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
OomError::OutOfHostMemory => "no memory available on the host",
|
OomError::OutOfHostMemory => "no memory available on the host",
|
||||||
OomError::OutOfDeviceMemory => "no memory available on the graphical device",
|
OomError::OutOfDeviceMemory => "no memory available on the graphical device",
|
||||||
}
|
}
|
||||||
@ -165,7 +164,6 @@ impl Display for OomError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for OomError {
|
impl From<VulkanError> for OomError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> OomError {
|
fn from(err: VulkanError) -> OomError {
|
||||||
match err {
|
match err {
|
||||||
VulkanError::OutOfHostMemory => OomError::OutOfHostMemory,
|
VulkanError::OutOfHostMemory => OomError::OutOfHostMemory,
|
||||||
@ -182,117 +180,79 @@ impl Error for VulkanError {}
|
|||||||
|
|
||||||
impl Display for VulkanError {
|
impl Display for VulkanError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
write!(
|
||||||
VulkanError::OutOfHostMemory => write!(
|
f,
|
||||||
f,
|
"{}",
|
||||||
"A host memory allocation has failed.",
|
match self {
|
||||||
),
|
VulkanError::OutOfHostMemory => "a host memory allocation has failed",
|
||||||
VulkanError::OutOfDeviceMemory => write!(
|
VulkanError::OutOfDeviceMemory => "a device memory allocation has failed",
|
||||||
f,
|
VulkanError::InitializationFailed => {
|
||||||
"A device memory allocation has failed.",
|
"initialization of an object could not be completed for \
|
||||||
),
|
implementation-specific reasons"
|
||||||
VulkanError::InitializationFailed => write!(
|
}
|
||||||
f,
|
VulkanError::DeviceLost => "the logical or physical device has been lost",
|
||||||
"Initialization of an object could not be completed for implementation-specific reasons.",
|
VulkanError::MemoryMapFailed => "mapping of a memory object has failed",
|
||||||
),
|
VulkanError::LayerNotPresent => {
|
||||||
VulkanError::DeviceLost => write!(
|
"a requested layer is not present or could not be loaded"
|
||||||
f,
|
}
|
||||||
"The logical or physical device has been lost.",
|
VulkanError::ExtensionNotPresent => "a requested extension is not supported",
|
||||||
),
|
VulkanError::FeatureNotPresent => "a requested feature is not supported",
|
||||||
VulkanError::MemoryMapFailed => write!(
|
VulkanError::IncompatibleDriver => {
|
||||||
f,
|
"the requested version of Vulkan is not supported by the driver or is \
|
||||||
"Mapping of a memory object has failed.",
|
otherwise incompatible for implementation-specific reasons"
|
||||||
),
|
}
|
||||||
VulkanError::LayerNotPresent => write!(
|
VulkanError::TooManyObjects => {
|
||||||
f,
|
"too many objects of the type have already been created"
|
||||||
"A requested layer is not present or could not be loaded.",
|
}
|
||||||
),
|
VulkanError::FormatNotSupported => {
|
||||||
VulkanError::ExtensionNotPresent => write!(
|
"a requested format is not supported on this device"
|
||||||
f,
|
}
|
||||||
"A requested extension is not supported.",
|
VulkanError::FragmentedPool => {
|
||||||
),
|
"a pool allocation has failed due to fragmentation of the pool's memory"
|
||||||
VulkanError::FeatureNotPresent => write!(
|
}
|
||||||
f,
|
VulkanError::Unknown => {
|
||||||
"A requested feature is not supported.",
|
"an unknown error has occurred; either the application has provided invalid \
|
||||||
),
|
input, or an implementation failure has occurred"
|
||||||
VulkanError::IncompatibleDriver => write!(
|
}
|
||||||
f,
|
VulkanError::OutOfPoolMemory => "a pool memory allocation has failed",
|
||||||
"The requested version of Vulkan is not supported by the driver or is otherwise incompatible for implementation-specific reasons.",
|
VulkanError::InvalidExternalHandle => {
|
||||||
),
|
"an external handle is not a valid handle of the specified type"
|
||||||
VulkanError::TooManyObjects => write!(
|
}
|
||||||
f,
|
VulkanError::Fragmentation => {
|
||||||
"Too many objects of the type have already been created.",
|
"a descriptor pool creation has failed due to fragmentation"
|
||||||
),
|
}
|
||||||
VulkanError::FormatNotSupported => write!(
|
VulkanError::InvalidOpaqueCaptureAddress => {
|
||||||
f,
|
"a buffer creation or memory allocation failed because the requested address \
|
||||||
"A requested format is not supported on this device.",
|
is not available. A shader group handle assignment failed because the \
|
||||||
),
|
requested shader group handle information is no longer valid"
|
||||||
VulkanError::FragmentedPool => write!(
|
}
|
||||||
f,
|
VulkanError::IncompatibleDisplay => {
|
||||||
"A pool allocation has failed due to fragmentation of the pool's memory.",
|
"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::Unknown => write!(
|
}
|
||||||
f,
|
VulkanError::NotPermitted => "a requested operation was not permitted",
|
||||||
"An unknown error has occurred; either the application has provided invalid input, or an implementation failure has occurred.",
|
VulkanError::SurfaceLost => "a surface is no longer available",
|
||||||
),
|
VulkanError::NativeWindowInUse => {
|
||||||
VulkanError::OutOfPoolMemory => write!(
|
"the requested window is already in use by Vulkan or another API in a manner \
|
||||||
f,
|
which prevents it from being used again"
|
||||||
"A pool memory allocation has failed.",
|
}
|
||||||
),
|
VulkanError::OutOfDate => {
|
||||||
VulkanError::InvalidExternalHandle => write!(
|
"a surface has changed in such a way that it is no longer compatible with the \
|
||||||
f,
|
swapchain, and further presentation requests using the swapchain will fail"
|
||||||
"An external handle is not a valid handle of the specified type.",
|
}
|
||||||
),
|
VulkanError::ValidationFailed => "validation failed",
|
||||||
VulkanError::Fragmentation => write!(
|
VulkanError::FullScreenExclusiveModeLost => {
|
||||||
f,
|
"an operation on a swapchain created with application controlled full-screen \
|
||||||
"A descriptor pool creation has failed due to fragmentation.",
|
access failed as it did not have exclusive full-screen access"
|
||||||
),
|
}
|
||||||
VulkanError::InvalidOpaqueCaptureAddress => write!(
|
VulkanError::InvalidDrmFormatModifierPlaneLayout => {
|
||||||
f,
|
"the requested DRM format modifier plane layout is invalid"
|
||||||
"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::InvalidShader => "one or more shaders failed to compile or link",
|
||||||
VulkanError::IncompatibleDisplay => write!(
|
VulkanError::Unnamed(result) =>
|
||||||
f,
|
return write!(f, "unnamed error, VkResult value {}", result.as_raw()),
|
||||||
"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(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,7 +275,6 @@ pub struct RequiresOneOf {
|
|||||||
|
|
||||||
impl RequiresOneOf {
|
impl RequiresOneOf {
|
||||||
/// Returns whether there is more than one possible requirement.
|
/// Returns whether there is more than one possible requirement.
|
||||||
#[inline]
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.api_version.map_or(0, |_| 1)
|
self.api_version.map_or(0, |_| 1)
|
||||||
+ self.features.len()
|
+ self.features.len()
|
||||||
@ -325,7 +284,6 @@ impl RequiresOneOf {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for RequiresOneOf {
|
impl Display for RequiresOneOf {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
let mut members_written = 0;
|
let mut members_written = 0;
|
||||||
|
|
||||||
|
@ -53,6 +53,7 @@ impl VulkanLibrary {
|
|||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn def_loader_impl() -> Result<Box<dyn Loader>, LoadingError> {
|
fn def_loader_impl() -> Result<Box<dyn Loader>, LoadingError> {
|
||||||
let loader = crate::statically_linked_vulkan_loader!();
|
let loader = crate::statically_linked_vulkan_loader!();
|
||||||
|
|
||||||
Ok(Box::new(loader))
|
Ok(Box::new(loader))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,6 +178,7 @@ impl VulkanLibrary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the highest Vulkan version that is supported for instances.
|
/// Returns the highest Vulkan version that is supported for instances.
|
||||||
|
#[inline]
|
||||||
pub fn api_version(&self) -> Version {
|
pub fn api_version(&self) -> Version {
|
||||||
self.api_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
|
/// > here is no longer available when you create the `Instance`. This will lead to an error
|
||||||
/// > when calling `Instance::new`.
|
/// > when calling `Instance::new`.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vulkano::VulkanLibrary;
|
/// use vulkano::VulkanLibrary;
|
||||||
@ -315,7 +317,6 @@ where
|
|||||||
T: SafeDeref + Send + Sync,
|
T: SafeDeref + Send + Sync,
|
||||||
T::Target: Loader,
|
T::Target: Loader,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
unsafe fn get_instance_proc_addr(
|
unsafe fn get_instance_proc_addr(
|
||||||
&self,
|
&self,
|
||||||
instance: ash::vk::Instance,
|
instance: ash::vk::Instance,
|
||||||
@ -326,7 +327,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for dyn Loader {
|
impl Debug for dyn Loader {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, _f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -416,23 +416,21 @@ pub enum LoadingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for LoadingError {
|
impl Error for LoadingError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
//Self::LibraryLoadFailure(ref err) => Some(err),
|
//Self::LibraryLoadFailure(err) => Some(err),
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for LoadingError {
|
impl Display for LoadingError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
Self::LibraryLoadFailure(_) => "failed to load the Vulkan shared library",
|
Self::LibraryLoadFailure(_) => "failed to load the Vulkan shared library",
|
||||||
Self::OomError(_) => "not enough memory available",
|
Self::OomError(_) => "not enough memory available",
|
||||||
}
|
}
|
||||||
@ -441,7 +439,6 @@ impl Display for LoadingError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for LoadingError {
|
impl From<VulkanError> for LoadingError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
|
@ -29,7 +29,7 @@ use std::{
|
|||||||
///
|
///
|
||||||
/// The destructor of `DeviceMemory` automatically frees the memory.
|
/// The destructor of `DeviceMemory` automatically frees the memory.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
|
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
|
||||||
@ -547,6 +547,7 @@ impl DeviceMemory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn commitment_unchecked(&self) -> DeviceSize {
|
pub unsafe fn commitment_unchecked(&self) -> DeviceSize {
|
||||||
let mut output: DeviceSize = 0;
|
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`.
|
/// 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.
|
/// - Panics if the user requests an invalid handle type for this device memory object.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -617,6 +618,7 @@ impl DeviceMemory {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let file = unsafe { std::fs::File::from_raw_fd(fd) };
|
let file = unsafe { std::fs::File::from_raw_fd(fd) };
|
||||||
|
|
||||||
Ok(file)
|
Ok(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -660,7 +662,6 @@ impl PartialEq for DeviceMemory {
|
|||||||
impl Eq for DeviceMemory {}
|
impl Eq for DeviceMemory {}
|
||||||
|
|
||||||
impl Hash for DeviceMemory {
|
impl Hash for DeviceMemory {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device.hash(state);
|
self.device.hash(state);
|
||||||
@ -709,6 +710,7 @@ impl Default for MemoryAllocateInfo<'static> {
|
|||||||
|
|
||||||
impl<'d> MemoryAllocateInfo<'d> {
|
impl<'d> MemoryAllocateInfo<'d> {
|
||||||
/// Returns a `MemoryAllocateInfo` with the specified `dedicated_allocation`.
|
/// Returns a `MemoryAllocateInfo` with the specified `dedicated_allocation`.
|
||||||
|
#[inline]
|
||||||
pub fn dedicated_allocation(dedicated_allocation: DedicatedAllocation<'d>) -> Self {
|
pub fn dedicated_allocation(dedicated_allocation: DedicatedAllocation<'d>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
allocation_size: 0,
|
allocation_size: 0,
|
||||||
@ -748,6 +750,7 @@ pub enum MemoryImportInfo {
|
|||||||
handle_type: ExternalMemoryHandleType,
|
handle_type: ExternalMemoryHandleType,
|
||||||
file: File,
|
file: File,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Import memory from a Windows handle.
|
/// Import memory from a Windows handle.
|
||||||
///
|
///
|
||||||
/// `handle_type` must be either [`ExternalMemoryHandleType::OpaqueWin32`] or
|
/// `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
|
/// Describes a handle type used for Vulkan external memory apis. This is **not** just a
|
||||||
/// suggestion. Check out vkExternalMemoryHandleTypeFlagBits in the Vulkan spec.
|
/// 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
|
/// If you specify an handle type that doesnt make sense (for example, using a dma-buf handle
|
||||||
/// on Windows) when using this handle, a panic will happen.
|
/// type on Windows) when using this handle, a panic will happen.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
ExternalMemoryHandleType = ExternalMemoryHandleTypeFlags(u32);
|
ExternalMemoryHandleType = ExternalMemoryHandleTypeFlags(u32);
|
||||||
|
|
||||||
@ -1000,26 +1003,23 @@ pub enum DeviceMemoryError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for DeviceMemoryError {
|
impl Error for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
Self::MemoryMapError(ref err) => Some(err),
|
Self::MemoryMapError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for DeviceMemoryError {
|
impl Display for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
Self::TooManyObjects => {
|
Self::TooManyObjects => {
|
||||||
write!(f, "the maximum number of allocations has been exceeded")
|
write!(f, "the maximum number of allocations has been exceeded")
|
||||||
}
|
}
|
||||||
Self::MemoryMapError(_) => write!(f, "error occurred when mapping the memory"),
|
Self::MemoryMapError(_) => write!(f, "error occurred when mapping the memory"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1028,22 +1028,25 @@ impl Display for DeviceMemoryError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::DedicatedAllocationSizeMismatch {
|
||||||
Self::DedicatedAllocationSizeMismatch { allocation_size, required_size } => write!(
|
allocation_size,
|
||||||
f,
|
required_size,
|
||||||
"`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!(
|
} => write!(
|
||||||
f,
|
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,
|
handle_type,
|
||||||
),
|
),
|
||||||
Self::ImportFdHandleTypeNotSupported { handle_type } => write!(
|
Self::ImportFdHandleTypeNotSupported { handle_type } => write!(
|
||||||
f,
|
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,
|
handle_type,
|
||||||
),
|
),
|
||||||
Self::ImportWin32HandleTypeNotSupported { handle_type } => write!(
|
Self::ImportWin32HandleTypeNotSupported { handle_type } => write!(
|
||||||
@ -1051,19 +1054,28 @@ impl Display for DeviceMemoryError {
|
|||||||
"the provided `MemoryImportInfo::Win32::handle_type` ({:?}) is not supported",
|
"the provided `MemoryImportInfo::Win32::handle_type` ({:?}) is not supported",
|
||||||
handle_type,
|
handle_type,
|
||||||
),
|
),
|
||||||
Self::MemoryTypeHeapSizeExceeded { allocation_size, heap_size } => write!(
|
Self::MemoryTypeHeapSizeExceeded {
|
||||||
|
allocation_size,
|
||||||
|
heap_size,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
allocation_size, heap_size,
|
||||||
),
|
),
|
||||||
Self::MemoryTypeIndexOutOfRange { memory_type_index, memory_type_count } => write!(
|
Self::MemoryTypeIndexOutOfRange {
|
||||||
|
memory_type_index,
|
||||||
|
memory_type_count,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
memory_type_index, memory_type_count,
|
||||||
),
|
),
|
||||||
Self::NotLazilyAllocated => write!(
|
Self::NotLazilyAllocated => write!(
|
||||||
f,
|
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) => {
|
Self::SpecViolation(u) => {
|
||||||
@ -1077,7 +1089,6 @@ impl Display for DeviceMemoryError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for DeviceMemoryError {
|
impl From<VulkanError> for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||||
@ -1090,21 +1101,18 @@ impl From<VulkanError> for DeviceMemoryError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for DeviceMemoryError {
|
impl From<OomError> for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MemoryMapError> for DeviceMemoryError {
|
impl From<MemoryMapError> for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: MemoryMapError) -> Self {
|
fn from(err: MemoryMapError) -> Self {
|
||||||
Self::MemoryMapError(err)
|
Self::MemoryMapError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for DeviceMemoryError {
|
impl From<RequirementNotMet> for DeviceMemoryError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
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`
|
/// In order to access the contents of the allocated memory, you can use the `read` and `write`
|
||||||
/// methods.
|
/// methods.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use vulkano::memory::{DeviceMemory, MappedDeviceMemory, MemoryAllocateInfo};
|
/// use vulkano::memory::{DeviceMemory, MappedDeviceMemory, MemoryAllocateInfo};
|
||||||
@ -1132,7 +1140,7 @@ impl From<RequirementNotMet> for DeviceMemoryError {
|
|||||||
/// .iter()
|
/// .iter()
|
||||||
/// .position(|t| t.property_flags.host_visible)
|
/// .position(|t| t.property_flags.host_visible)
|
||||||
/// .map(|i| i as u32)
|
/// .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.
|
/// // Allocates 1KB of memory.
|
||||||
/// let memory = DeviceMemory::allocate(
|
/// let memory = DeviceMemory::allocate(
|
||||||
@ -1142,7 +1150,8 @@ impl From<RequirementNotMet> for DeviceMemoryError {
|
|||||||
/// memory_type_index,
|
/// memory_type_index,
|
||||||
/// ..Default::default()
|
/// ..Default::default()
|
||||||
/// },
|
/// },
|
||||||
/// ).unwrap();
|
/// )
|
||||||
|
/// .unwrap();
|
||||||
/// let mapped_memory = MappedDeviceMemory::new(memory, 0..1024).unwrap();
|
/// let mapped_memory = MappedDeviceMemory::new(memory, 0..1024).unwrap();
|
||||||
///
|
///
|
||||||
/// // Get access to the content.
|
/// // Get access to the content.
|
||||||
@ -1167,7 +1176,6 @@ pub struct MappedDeviceMemory {
|
|||||||
//
|
//
|
||||||
// Vulkan specs, documentation of `vkFreeMemory`:
|
// Vulkan specs, documentation of `vkFreeMemory`:
|
||||||
// > If a memory object is mapped at the time it is freed, it is implicitly unmapped.
|
// > If a memory object is mapped at the time it is freed, it is implicitly unmapped.
|
||||||
//
|
|
||||||
|
|
||||||
impl MappedDeviceMemory {
|
impl MappedDeviceMemory {
|
||||||
/// Maps a range of memory to be accessed by the CPU.
|
/// 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.
|
/// Unmaps the memory. It will no longer be accessible from the CPU.
|
||||||
|
#[inline]
|
||||||
pub fn unmap(self) -> DeviceMemory {
|
pub fn unmap(self) -> DeviceMemory {
|
||||||
unsafe {
|
unsafe {
|
||||||
let device = self.memory.device();
|
let device = self.memory.device();
|
||||||
@ -1278,6 +1287,7 @@ impl MappedDeviceMemory {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `range` is empty.
|
/// - Panics if `range` is empty.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
|
pub unsafe fn invalidate_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
|
||||||
if self.coherent {
|
if self.coherent {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -1327,6 +1337,7 @@ impl MappedDeviceMemory {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `range` is empty.
|
/// - Panics if `range` is empty.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
|
pub unsafe fn flush_range(&self, range: Range<DeviceSize>) -> Result<(), MemoryMapError> {
|
||||||
self.check_range(range.clone())?;
|
self.check_range(range.clone())?;
|
||||||
|
|
||||||
@ -1370,6 +1381,7 @@ impl MappedDeviceMemory {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `range` is empty.
|
/// - Panics if `range` is empty.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn read(&self, range: Range<DeviceSize>) -> Result<&[u8], MemoryMapError> {
|
pub unsafe fn read(&self, range: Range<DeviceSize>) -> Result<&[u8], MemoryMapError> {
|
||||||
self.check_range(range.clone())?;
|
self.check_range(range.clone())?;
|
||||||
|
|
||||||
@ -1399,6 +1411,7 @@ impl MappedDeviceMemory {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `range` is empty.
|
/// - Panics if `range` is empty.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn write(&self, range: Range<DeviceSize>) -> Result<&mut [u8], MemoryMapError> {
|
pub unsafe fn write(&self, range: Range<DeviceSize>) -> Result<&mut [u8], MemoryMapError> {
|
||||||
self.check_range(range.clone())?;
|
self.check_range(range.clone())?;
|
||||||
|
|
||||||
@ -1491,41 +1504,42 @@ pub enum MemoryMapError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for MemoryMapError {
|
impl Error for MemoryMapError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for MemoryMapError {
|
impl Display for MemoryMapError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
Self::MemoryMapFailed => write!(f, "memory map failed"),
|
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,
|
f,
|
||||||
"tried to map memory whose type is not host-visible",
|
"the specified `range` ({:?}) was not contained within the allocated or mapped \
|
||||||
),
|
memory range ({:?})",
|
||||||
Self::OutOfRange { ref provided_range, ref allowed_range } => write!(
|
|
||||||
f,
|
|
||||||
"the specified `range` ({:?}) was not contained within the allocated or mapped memory range ({:?})",
|
|
||||||
provided_range, allowed_range,
|
provided_range, allowed_range,
|
||||||
),
|
),
|
||||||
Self::RangeNotAlignedToAtomSize { ref range, atom_size } => write!(
|
Self::RangeNotAlignedToAtomSize { range, atom_size } => write!(
|
||||||
f,
|
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,
|
range, atom_size,
|
||||||
)
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for MemoryMapError {
|
impl From<VulkanError> for MemoryMapError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||||
@ -1538,7 +1552,6 @@ impl From<VulkanError> for MemoryMapError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for MemoryMapError {
|
impl From<OomError> for MemoryMapError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ impl PipelineCache {
|
|||||||
/// implementation. Therefore you can easily crash your application or the system by passing
|
/// implementation. Therefore you can easily crash your application or the system by passing
|
||||||
/// wrong data. Hence why this function is unsafe.
|
/// wrong data. Hence why this function is unsafe.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// This example loads a cache from a file, if it exists.
|
/// 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.
|
/// 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();
|
/// let mut data = Vec::new();
|
||||||
/// if let Ok(_) = file.read_to_end(&mut data) {
|
/// if let Ok(_) = file.read_to_end(&mut data) {
|
||||||
/// Some(data)
|
/// Some(data)
|
||||||
/// } else { None }
|
/// } else {
|
||||||
/// } else { None }
|
/// None
|
||||||
|
/// }
|
||||||
|
/// } else {
|
||||||
|
/// None
|
||||||
|
/// }
|
||||||
/// };
|
/// };
|
||||||
///
|
///
|
||||||
/// let cache = if let Some(data) = data {
|
/// let cache = if let Some(data) = data {
|
||||||
@ -82,7 +86,7 @@ impl PipelineCache {
|
|||||||
|
|
||||||
/// Builds a new empty pipeline cache.
|
/// Builds a new empty pipeline cache.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// # use std::sync::Arc;
|
/// # 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.
|
/// 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.
|
/// - 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`.
|
/// 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.
|
/// This example stores the data of a pipeline cache on the disk.
|
||||||
/// See [`with_data`](#method.with_data) for how to reload it.
|
/// 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> {
|
pub fn get_data(&self) -> Result<Vec<u8>, OomError> {
|
||||||
let fns = self.device.fns();
|
let fns = self.device.fns();
|
||||||
|
|
||||||
|
@ -273,7 +273,6 @@ impl Pipeline for ComputePipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for ComputePipeline {
|
impl Debug for ComputePipeline {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(f, "<Vulkan compute pipeline {:?}>", self.handle)
|
write!(f, "<Vulkan compute pipeline {:?}>", self.handle)
|
||||||
}
|
}
|
||||||
@ -330,25 +329,23 @@ pub enum ComputePipelineCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ComputePipelineCreationError {
|
impl Error for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
Self::DescriptorSetLayoutCreationError(ref err) => Some(err),
|
Self::DescriptorSetLayoutCreationError(err) => Some(err),
|
||||||
Self::PipelineLayoutCreationError(ref err) => Some(err),
|
Self::PipelineLayoutCreationError(err) => Some(err),
|
||||||
Self::IncompatiblePipelineLayout(ref err) => Some(err),
|
Self::IncompatiblePipelineLayout(err) => Some(err),
|
||||||
Self::IncompatibleSpecializationConstants => None,
|
Self::IncompatibleSpecializationConstants => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ComputePipelineCreationError {
|
impl Display for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
ComputePipelineCreationError::OomError(_) => "not enough memory available",
|
ComputePipelineCreationError::OomError(_) => "not enough memory available",
|
||||||
ComputePipelineCreationError::DescriptorSetLayoutCreationError(_) => {
|
ComputePipelineCreationError::DescriptorSetLayoutCreationError(_) => {
|
||||||
"error while creating a descriptor set layout object"
|
"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"
|
"the pipeline layout is not compatible with what the shader expects"
|
||||||
}
|
}
|
||||||
ComputePipelineCreationError::IncompatibleSpecializationConstants => {
|
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 {
|
impl From<OomError> for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> ComputePipelineCreationError {
|
fn from(err: OomError) -> ComputePipelineCreationError {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DescriptorSetLayoutCreationError> for ComputePipelineCreationError {
|
impl From<DescriptorSetLayoutCreationError> for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DescriptorSetLayoutCreationError) -> Self {
|
fn from(err: DescriptorSetLayoutCreationError) -> Self {
|
||||||
Self::DescriptorSetLayoutCreationError(err)
|
Self::DescriptorSetLayoutCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PipelineLayoutCreationError> for ComputePipelineCreationError {
|
impl From<PipelineLayoutCreationError> for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: PipelineLayoutCreationError) -> Self {
|
fn from(err: PipelineLayoutCreationError) -> Self {
|
||||||
Self::PipelineLayoutCreationError(err)
|
Self::PipelineLayoutCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PipelineLayoutSupersetError> for ComputePipelineCreationError {
|
impl From<PipelineLayoutSupersetError> for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: PipelineLayoutSupersetError) -> Self {
|
fn from(err: PipelineLayoutSupersetError) -> Self {
|
||||||
Self::IncompatiblePipelineLayout(err)
|
Self::IncompatiblePipelineLayout(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for ComputePipelineCreationError {
|
impl From<VulkanError> for ComputePipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> ComputePipelineCreationError {
|
fn from(err: VulkanError) -> ComputePipelineCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
|
@ -151,6 +151,7 @@ where
|
|||||||
Fss: SpecializationConstants,
|
Fss: SpecializationConstants,
|
||||||
{
|
{
|
||||||
/// Builds the graphics pipeline, using an inferred a pipeline layout.
|
/// Builds the graphics pipeline, using an inferred a pipeline layout.
|
||||||
|
#[inline]
|
||||||
pub fn build(
|
pub fn build(
|
||||||
self,
|
self,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
@ -264,6 +265,7 @@ where
|
|||||||
/// Does the same as `build`, except that `build` automatically builds the pipeline layout
|
/// 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
|
/// object corresponding to the union of your shaders while this function allows you to specify
|
||||||
/// the pipeline layout.
|
/// the pipeline layout.
|
||||||
|
#[inline]
|
||||||
pub fn with_pipeline_layout(
|
pub fn with_pipeline_layout(
|
||||||
mut self,
|
mut self,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
@ -293,12 +295,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let has = {
|
let has = {
|
||||||
let &Self {
|
let Self {
|
||||||
ref render_pass,
|
render_pass,
|
||||||
cache: _,
|
cache: _,
|
||||||
|
|
||||||
ref vertex_shader,
|
vertex_shader,
|
||||||
ref tessellation_shaders,
|
tessellation_shaders,
|
||||||
geometry_shader: _,
|
geometry_shader: _,
|
||||||
fragment_shader: _,
|
fragment_shader: _,
|
||||||
|
|
||||||
@ -307,7 +309,7 @@ where
|
|||||||
tessellation_state: _,
|
tessellation_state: _,
|
||||||
viewport_state: _,
|
viewport_state: _,
|
||||||
discard_rectangle_state: _,
|
discard_rectangle_state: _,
|
||||||
ref rasterization_state,
|
rasterization_state,
|
||||||
multisample_state: _,
|
multisample_state: _,
|
||||||
depth_stencil_state: _,
|
depth_stencil_state: _,
|
||||||
color_blend_state: _,
|
color_blend_state: _,
|
||||||
@ -423,24 +425,24 @@ where
|
|||||||
let physical_device = device.physical_device();
|
let physical_device = device.physical_device();
|
||||||
let properties = physical_device.properties();
|
let properties = physical_device.properties();
|
||||||
|
|
||||||
let &Self {
|
let Self {
|
||||||
ref render_pass,
|
render_pass,
|
||||||
cache: _,
|
cache: _,
|
||||||
|
|
||||||
ref vertex_shader,
|
vertex_shader,
|
||||||
ref tessellation_shaders,
|
tessellation_shaders,
|
||||||
ref geometry_shader,
|
geometry_shader,
|
||||||
ref fragment_shader,
|
fragment_shader,
|
||||||
|
|
||||||
vertex_input_state: _,
|
vertex_input_state: _,
|
||||||
ref input_assembly_state,
|
input_assembly_state,
|
||||||
ref tessellation_state,
|
tessellation_state,
|
||||||
ref viewport_state,
|
viewport_state,
|
||||||
ref discard_rectangle_state,
|
discard_rectangle_state,
|
||||||
ref rasterization_state,
|
rasterization_state,
|
||||||
ref multisample_state,
|
multisample_state,
|
||||||
ref depth_stencil_state,
|
depth_stencil_state,
|
||||||
ref color_blend_state,
|
color_blend_state,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let render_pass = render_pass.as_ref().expect("Missing render pass");
|
let render_pass = render_pass.as_ref().expect("Missing render pass");
|
||||||
@ -595,9 +597,9 @@ where
|
|||||||
// Vertex input state
|
// Vertex input state
|
||||||
// VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-04910
|
// VUID-VkGraphicsPipelineCreateInfo-pVertexInputState-04910
|
||||||
{
|
{
|
||||||
let &VertexInputState {
|
let VertexInputState {
|
||||||
ref bindings,
|
bindings,
|
||||||
ref attributes,
|
attributes,
|
||||||
} = vertex_input_state;
|
} = vertex_input_state;
|
||||||
|
|
||||||
// VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613
|
// VUID-VkPipelineVertexInputStateCreateInfo-vertexBindingDescriptionCount-00613
|
||||||
@ -1406,18 +1408,15 @@ where
|
|||||||
|
|
||||||
// Discard rectangle state
|
// Discard rectangle state
|
||||||
{
|
{
|
||||||
let &DiscardRectangleState {
|
let DiscardRectangleState { mode, rectangles } = discard_rectangle_state;
|
||||||
mode,
|
|
||||||
ref rectangles,
|
|
||||||
} = discard_rectangle_state;
|
|
||||||
|
|
||||||
if device.enabled_extensions().ext_discard_rectangles {
|
if device.enabled_extensions().ext_discard_rectangles {
|
||||||
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleMode-parameter
|
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleMode-parameter
|
||||||
mode.validate_device(device)?;
|
mode.validate_device(device)?;
|
||||||
|
|
||||||
let discard_rectangle_count = match *rectangles {
|
let discard_rectangle_count = match rectangles {
|
||||||
PartialStateMode::Dynamic(count) => count,
|
PartialStateMode::Dynamic(count) => *count,
|
||||||
PartialStateMode::Fixed(ref rectangles) => rectangles.len() as u32,
|
PartialStateMode::Fixed(rectangles) => rectangles.len() as u32,
|
||||||
};
|
};
|
||||||
|
|
||||||
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582
|
// VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582
|
||||||
@ -1430,9 +1429,9 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let error = match *rectangles {
|
let error = match rectangles {
|
||||||
PartialStateMode::Dynamic(_) => true,
|
PartialStateMode::Dynamic(_) => true,
|
||||||
PartialStateMode::Fixed(ref rectangles) => !rectangles.is_empty(),
|
PartialStateMode::Fixed(rectangles) => !rectangles.is_empty(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if error {
|
if error {
|
||||||
@ -1503,8 +1502,8 @@ where
|
|||||||
// VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750
|
// VUID-VkGraphicsPipelineCreateInfo-rasterizerDiscardEnable-00750
|
||||||
// VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892
|
// VUID-VkGraphicsPipelineCreateInfo-pViewportState-04892
|
||||||
if has.viewport_state {
|
if has.viewport_state {
|
||||||
let (viewport_count, scissor_count) = match *viewport_state {
|
let (viewport_count, scissor_count) = match viewport_state {
|
||||||
ViewportState::Fixed { ref data } => {
|
ViewportState::Fixed { data } => {
|
||||||
let count = data.len() as u32;
|
let count = data.len() as u32;
|
||||||
assert!(count != 0); // TODO: return error?
|
assert!(count != 0); // TODO: return error?
|
||||||
|
|
||||||
@ -1533,7 +1532,7 @@ where
|
|||||||
(count, count)
|
(count, count)
|
||||||
}
|
}
|
||||||
ViewportState::FixedViewport {
|
ViewportState::FixedViewport {
|
||||||
ref viewports,
|
viewports,
|
||||||
scissor_count_dynamic,
|
scissor_count_dynamic,
|
||||||
} => {
|
} => {
|
||||||
let viewport_count = viewports.len() as u32;
|
let viewport_count = viewports.len() as u32;
|
||||||
@ -1560,7 +1559,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-VkPipelineViewportStateCreateInfo-scissorCount-04136
|
// 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
|
if !(device.api_version() >= Version::V1_3
|
||||||
|| device.enabled_features().extended_dynamic_state)
|
|| device.enabled_features().extended_dynamic_state)
|
||||||
{
|
{
|
||||||
@ -1583,7 +1582,7 @@ where
|
|||||||
(viewport_count, scissor_count)
|
(viewport_count, scissor_count)
|
||||||
}
|
}
|
||||||
ViewportState::FixedScissor {
|
ViewportState::FixedScissor {
|
||||||
ref scissors,
|
scissors,
|
||||||
viewport_count_dynamic,
|
viewport_count_dynamic,
|
||||||
} => {
|
} => {
|
||||||
let scissor_count = scissors.len() as u32;
|
let scissor_count = scissors.len() as u32;
|
||||||
@ -1592,7 +1591,7 @@ where
|
|||||||
assert!(scissor_count != 0); // TODO: return error?
|
assert!(scissor_count != 0); // TODO: return error?
|
||||||
|
|
||||||
// VUID-VkPipelineViewportStateCreateInfo-viewportCount-04135
|
// 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
|
if !(device.api_version() >= Version::V1_3
|
||||||
|| device.enabled_features().extended_dynamic_state)
|
|| device.enabled_features().extended_dynamic_state)
|
||||||
{
|
{
|
||||||
@ -1618,7 +1617,7 @@ where
|
|||||||
|
|
||||||
(viewport_count, scissor_count)
|
(viewport_count, scissor_count)
|
||||||
}
|
}
|
||||||
ViewportState::Dynamic {
|
&ViewportState::Dynamic {
|
||||||
count,
|
count,
|
||||||
viewport_count_dynamic,
|
viewport_count_dynamic,
|
||||||
scissor_count_dynamic,
|
scissor_count_dynamic,
|
||||||
@ -1764,10 +1763,10 @@ where
|
|||||||
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
|
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06053
|
||||||
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06590
|
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06590
|
||||||
if has.depth_stencil_state {
|
if has.depth_stencil_state {
|
||||||
let &DepthStencilState {
|
let DepthStencilState {
|
||||||
ref depth,
|
depth,
|
||||||
ref depth_bounds,
|
depth_bounds,
|
||||||
ref stencil,
|
stencil,
|
||||||
} = depth_stencil_state;
|
} = depth_stencil_state;
|
||||||
|
|
||||||
if let Some(depth_state) = depth {
|
if let Some(depth_state) = depth {
|
||||||
@ -1860,9 +1859,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(depth_bounds_state) = depth_bounds {
|
if let Some(depth_bounds_state) = depth_bounds {
|
||||||
let &DepthBoundsState {
|
let DepthBoundsState {
|
||||||
enable_dynamic,
|
enable_dynamic,
|
||||||
ref bounds,
|
bounds,
|
||||||
} = depth_bounds_state;
|
} = depth_bounds_state;
|
||||||
|
|
||||||
// VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598
|
// VUID-VkPipelineDepthStencilStateCreateInfo-depthBoundsTestEnable-00598
|
||||||
@ -1877,7 +1876,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if enable_dynamic
|
if *enable_dynamic
|
||||||
&& !(device.api_version() >= Version::V1_3
|
&& !(device.api_version() >= Version::V1_3
|
||||||
|| device.enabled_features().extended_dynamic_state)
|
|| device.enabled_features().extended_dynamic_state)
|
||||||
{
|
{
|
||||||
@ -1909,10 +1908,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stencil_state) = stencil {
|
if let Some(stencil_state) = stencil {
|
||||||
let &StencilState {
|
let StencilState {
|
||||||
enable_dynamic,
|
enable_dynamic,
|
||||||
ref front,
|
front,
|
||||||
ref back,
|
back,
|
||||||
} = stencil_state;
|
} = stencil_state;
|
||||||
|
|
||||||
let has_stencil_attachment = match render_pass {
|
let has_stencil_attachment = match render_pass {
|
||||||
@ -1927,7 +1926,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID?
|
// VUID?
|
||||||
if enable_dynamic
|
if *enable_dynamic
|
||||||
&& !(device.api_version() >= Version::V1_3
|
&& !(device.api_version() >= Version::V1_3
|
||||||
|| device.enabled_features().extended_dynamic_state)
|
|| device.enabled_features().extended_dynamic_state)
|
||||||
{
|
{
|
||||||
@ -2089,9 +2088,9 @@ where
|
|||||||
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06044
|
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06044
|
||||||
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06054
|
// VUID-VkGraphicsPipelineCreateInfo-renderPass-06054
|
||||||
if has.color_blend_state {
|
if has.color_blend_state {
|
||||||
let &ColorBlendState {
|
let ColorBlendState {
|
||||||
logic_op,
|
logic_op,
|
||||||
ref attachments,
|
attachments,
|
||||||
blend_constants: _,
|
blend_constants: _,
|
||||||
} = color_blend_state;
|
} = color_blend_state;
|
||||||
|
|
||||||
@ -2446,9 +2445,9 @@ where
|
|||||||
{
|
{
|
||||||
dynamic_state.insert(DynamicState::VertexInput, false);
|
dynamic_state.insert(DynamicState::VertexInput, false);
|
||||||
|
|
||||||
let &VertexInputState {
|
let VertexInputState {
|
||||||
ref bindings,
|
bindings,
|
||||||
ref attributes,
|
attributes,
|
||||||
} = vertex_input_state;
|
} = vertex_input_state;
|
||||||
|
|
||||||
vertex_binding_descriptions_vk.extend(bindings.iter().map(
|
vertex_binding_descriptions_vk.extend(bindings.iter().map(
|
||||||
@ -2865,27 +2864,26 @@ where
|
|||||||
|
|
||||||
// Discard rectangle state
|
// Discard rectangle state
|
||||||
if device.enabled_extensions().ext_discard_rectangles {
|
if device.enabled_extensions().ext_discard_rectangles {
|
||||||
let &DiscardRectangleState {
|
let DiscardRectangleState { mode, rectangles } = discard_rectangle_state;
|
||||||
mode,
|
|
||||||
ref rectangles,
|
|
||||||
} = discard_rectangle_state;
|
|
||||||
|
|
||||||
let discard_rectangle_count = match *rectangles {
|
let discard_rectangle_count = match rectangles {
|
||||||
PartialStateMode::Fixed(ref rectangles) => {
|
PartialStateMode::Fixed(rectangles) => {
|
||||||
dynamic_state.insert(DynamicState::DiscardRectangle, false);
|
dynamic_state.insert(DynamicState::DiscardRectangle, false);
|
||||||
discard_rectangles.extend(rectangles.iter().map(|&rect| rect.into()));
|
discard_rectangles.extend(rectangles.iter().map(|&rect| rect.into()));
|
||||||
|
|
||||||
discard_rectangles.len() as u32
|
discard_rectangles.len() as u32
|
||||||
}
|
}
|
||||||
PartialStateMode::Dynamic(count) => {
|
PartialStateMode::Dynamic(count) => {
|
||||||
dynamic_state.insert(DynamicState::DiscardRectangle, true);
|
dynamic_state.insert(DynamicState::DiscardRectangle, true);
|
||||||
count
|
|
||||||
|
*count
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let _ = discard_rectangle_state_vk.insert(
|
let _ = discard_rectangle_state_vk.insert(
|
||||||
ash::vk::PipelineDiscardRectangleStateCreateInfoEXT {
|
ash::vk::PipelineDiscardRectangleStateCreateInfoEXT {
|
||||||
flags: ash::vk::PipelineDiscardRectangleStateCreateFlagsEXT::empty(),
|
flags: ash::vk::PipelineDiscardRectangleStateCreateFlagsEXT::empty(),
|
||||||
discard_rectangle_mode: mode.into(),
|
discard_rectangle_mode: (*mode).into(),
|
||||||
discard_rectangle_count,
|
discard_rectangle_count,
|
||||||
p_discard_rectangles: discard_rectangles.as_ptr(),
|
p_discard_rectangles: discard_rectangles.as_ptr(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -2920,8 +2918,8 @@ where
|
|||||||
|
|
||||||
// Viewport state
|
// Viewport state
|
||||||
if has.viewport_state {
|
if has.viewport_state {
|
||||||
let (viewport_count, scissor_count) = match *viewport_state {
|
let (viewport_count, scissor_count) = match viewport_state {
|
||||||
ViewportState::Fixed { ref data } => {
|
ViewportState::Fixed { data } => {
|
||||||
let count = data.len() as u32;
|
let count = data.len() as u32;
|
||||||
viewports_vk.extend(data.iter().map(|e| e.0.clone().into()));
|
viewports_vk.extend(data.iter().map(|e| e.0.clone().into()));
|
||||||
dynamic_state.insert(DynamicState::Viewport, false);
|
dynamic_state.insert(DynamicState::Viewport, false);
|
||||||
@ -2934,7 +2932,7 @@ where
|
|||||||
(count, count)
|
(count, count)
|
||||||
}
|
}
|
||||||
ViewportState::FixedViewport {
|
ViewportState::FixedViewport {
|
||||||
ref viewports,
|
viewports,
|
||||||
scissor_count_dynamic,
|
scissor_count_dynamic,
|
||||||
} => {
|
} => {
|
||||||
let viewport_count = viewports.len() as u32;
|
let viewport_count = viewports.len() as u32;
|
||||||
@ -2942,7 +2940,7 @@ where
|
|||||||
dynamic_state.insert(DynamicState::Viewport, false);
|
dynamic_state.insert(DynamicState::Viewport, false);
|
||||||
dynamic_state.insert(DynamicState::ViewportWithCount, 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::Scissor, false);
|
||||||
dynamic_state.insert(DynamicState::ScissorWithCount, true);
|
dynamic_state.insert(DynamicState::ScissorWithCount, true);
|
||||||
0
|
0
|
||||||
@ -2955,15 +2953,15 @@ where
|
|||||||
(viewport_count, scissor_count)
|
(viewport_count, scissor_count)
|
||||||
}
|
}
|
||||||
ViewportState::FixedScissor {
|
ViewportState::FixedScissor {
|
||||||
ref scissors,
|
scissors,
|
||||||
viewport_count_dynamic,
|
viewport_count_dynamic,
|
||||||
} => {
|
} => {
|
||||||
let scissor_count = scissors.len() as u32;
|
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::Scissor, false);
|
||||||
dynamic_state.insert(DynamicState::ScissorWithCount, 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::Viewport, false);
|
||||||
dynamic_state.insert(DynamicState::ViewportWithCount, true);
|
dynamic_state.insert(DynamicState::ViewportWithCount, true);
|
||||||
0
|
0
|
||||||
@ -2975,7 +2973,7 @@ where
|
|||||||
|
|
||||||
(viewport_count, scissor_count)
|
(viewport_count, scissor_count)
|
||||||
}
|
}
|
||||||
ViewportState::Dynamic {
|
&ViewportState::Dynamic {
|
||||||
count,
|
count,
|
||||||
viewport_count_dynamic,
|
viewport_count_dynamic,
|
||||||
scissor_count_dynamic,
|
scissor_count_dynamic,
|
||||||
@ -2983,19 +2981,23 @@ where
|
|||||||
let viewport_count = if viewport_count_dynamic {
|
let viewport_count = if viewport_count_dynamic {
|
||||||
dynamic_state.insert(DynamicState::Viewport, false);
|
dynamic_state.insert(DynamicState::Viewport, false);
|
||||||
dynamic_state.insert(DynamicState::ViewportWithCount, true);
|
dynamic_state.insert(DynamicState::ViewportWithCount, true);
|
||||||
|
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
dynamic_state.insert(DynamicState::Viewport, true);
|
dynamic_state.insert(DynamicState::Viewport, true);
|
||||||
dynamic_state.insert(DynamicState::ViewportWithCount, false);
|
dynamic_state.insert(DynamicState::ViewportWithCount, false);
|
||||||
|
|
||||||
count
|
count
|
||||||
};
|
};
|
||||||
let scissor_count = if scissor_count_dynamic {
|
let scissor_count = if scissor_count_dynamic {
|
||||||
dynamic_state.insert(DynamicState::Scissor, false);
|
dynamic_state.insert(DynamicState::Scissor, false);
|
||||||
dynamic_state.insert(DynamicState::ScissorWithCount, true);
|
dynamic_state.insert(DynamicState::ScissorWithCount, true);
|
||||||
|
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
dynamic_state.insert(DynamicState::Scissor, true);
|
dynamic_state.insert(DynamicState::Scissor, true);
|
||||||
dynamic_state.insert(DynamicState::ScissorWithCount, false);
|
dynamic_state.insert(DynamicState::ScissorWithCount, false);
|
||||||
|
|
||||||
count
|
count
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3071,10 +3073,10 @@ where
|
|||||||
|
|
||||||
// Depth/stencil state
|
// Depth/stencil state
|
||||||
if has.depth_stencil_state {
|
if has.depth_stencil_state {
|
||||||
let &DepthStencilState {
|
let DepthStencilState {
|
||||||
ref depth,
|
depth,
|
||||||
ref depth_bounds,
|
depth_bounds,
|
||||||
ref stencil,
|
stencil,
|
||||||
} = depth_stencil_state;
|
} = depth_stencil_state;
|
||||||
|
|
||||||
let (depth_test_enable, depth_write_enable, depth_compare_op) =
|
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) =
|
let (depth_bounds_test_enable, min_depth_bounds, max_depth_bounds) =
|
||||||
if let Some(depth_bounds_state) = depth_bounds {
|
if let Some(depth_bounds_state) = depth_bounds {
|
||||||
let &DepthBoundsState {
|
let DepthBoundsState {
|
||||||
enable_dynamic,
|
enable_dynamic,
|
||||||
ref bounds,
|
bounds,
|
||||||
} = depth_bounds_state;
|
} = depth_bounds_state;
|
||||||
|
|
||||||
if enable_dynamic {
|
if *enable_dynamic {
|
||||||
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, true);
|
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, true);
|
||||||
} else {
|
} else {
|
||||||
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, false);
|
dynamic_state.insert(DynamicState::DepthBoundsTestEnable, false);
|
||||||
@ -3148,13 +3150,13 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (stencil_test_enable, front, back) = if let Some(stencil_state) = stencil {
|
let (stencil_test_enable, front, back) = if let Some(stencil_state) = stencil {
|
||||||
let &StencilState {
|
let StencilState {
|
||||||
enable_dynamic,
|
enable_dynamic,
|
||||||
ref front,
|
front,
|
||||||
ref back,
|
back,
|
||||||
} = stencil_state;
|
} = stencil_state;
|
||||||
|
|
||||||
if enable_dynamic {
|
if *enable_dynamic {
|
||||||
dynamic_state.insert(DynamicState::StencilTestEnable, true);
|
dynamic_state.insert(DynamicState::StencilTestEnable, true);
|
||||||
} else {
|
} else {
|
||||||
dynamic_state.insert(DynamicState::StencilTestEnable, false);
|
dynamic_state.insert(DynamicState::StencilTestEnable, false);
|
||||||
@ -3501,6 +3503,7 @@ where
|
|||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
output.assume_init()
|
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.
|
/// Sets the vertex shader to use.
|
||||||
// TODO: correct specialization constants
|
// TODO: correct specialization constants
|
||||||
#[inline]
|
|
||||||
pub fn vertex_shader<'vs2, Vss2>(
|
pub fn vertex_shader<'vs2, Vss2>(
|
||||||
self,
|
self,
|
||||||
shader: EntryPoint<'vs2>,
|
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.
|
/// Sets the tessellation shaders to use.
|
||||||
// TODO: correct specialization constants
|
// TODO: correct specialization constants
|
||||||
#[inline]
|
|
||||||
pub fn tessellation_shaders<'tcs2, 'tes2, Tcss2, Tess2>(
|
pub fn tessellation_shaders<'tcs2, 'tes2, Tcss2, Tess2>(
|
||||||
self,
|
self,
|
||||||
control_shader: EntryPoint<'tcs2>,
|
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.
|
/// Sets the geometry shader to use.
|
||||||
// TODO: correct specialization constants
|
// TODO: correct specialization constants
|
||||||
#[inline]
|
|
||||||
pub fn geometry_shader<'gs2, Gss2>(
|
pub fn geometry_shader<'gs2, Gss2>(
|
||||||
self,
|
self,
|
||||||
shader: EntryPoint<'gs2>,
|
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.
|
/// The fragment shader is run once for each pixel that is covered by each primitive.
|
||||||
// TODO: correct specialization constants
|
// TODO: correct specialization constants
|
||||||
#[inline]
|
|
||||||
pub fn fragment_shader<'fs2, Fss2>(
|
pub fn fragment_shader<'fs2, Fss2>(
|
||||||
self,
|
self,
|
||||||
shader: EntryPoint<'fs2>,
|
shader: EntryPoint<'fs2>,
|
||||||
@ -3667,7 +3666,6 @@ impl<'vs, 'tcs, 'tes, 'gs, 'fs, Vdef, Vss, Tcss, Tess, Gss, Fss>
|
|||||||
/// Sets the vertex input state.
|
/// Sets the vertex input state.
|
||||||
///
|
///
|
||||||
/// The default value is [`VertexInputState::default()`].
|
/// The default value is [`VertexInputState::default()`].
|
||||||
#[inline]
|
|
||||||
pub fn vertex_input_state<T>(
|
pub fn vertex_input_state<T>(
|
||||||
self,
|
self,
|
||||||
vertex_input_state: T,
|
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
|
/// You will most likely need to explicitly specify the template parameter to the type of a
|
||||||
/// vertex.
|
/// vertex.
|
||||||
#[deprecated(since = "0.27.0", note = "Use `vertex_input_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `vertex_input_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn vertex_input_single_buffer<V: Vertex>(
|
pub fn vertex_input_single_buffer<V: Vertex>(
|
||||||
self,
|
self,
|
||||||
) -> GraphicsPipelineBuilder<
|
) -> 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
|
/// Sets the viewports to some value, and the scissor boxes to boxes that always cover the
|
||||||
/// whole viewport.
|
/// whole viewport.
|
||||||
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn viewports<I>(self, viewports: I) -> Self
|
pub fn viewports<I>(self, viewports: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Viewport>,
|
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.
|
/// Sets the characteristics of viewports and scissor boxes in advance.
|
||||||
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn viewports_scissors<I>(mut self, viewports: I) -> Self
|
pub fn viewports_scissors<I>(mut self, viewports: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = (Viewport, Scissor)>,
|
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
|
/// Sets the scissor boxes to some values, and viewports to dynamic. The viewports will
|
||||||
/// need to be set before drawing.
|
/// need to be set before drawing.
|
||||||
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn viewports_dynamic_scissors_fixed<I>(mut self, scissors: I) -> Self
|
pub fn viewports_dynamic_scissors_fixed<I>(mut self, scissors: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Scissor>,
|
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
|
/// Sets the viewports to some values, and scissor boxes to dynamic. The scissor boxes will
|
||||||
/// need to be set before drawing.
|
/// need to be set before drawing.
|
||||||
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `viewport_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn viewports_fixed_scissors_dynamic<I>(mut self, viewports: I) -> Self
|
pub fn viewports_fixed_scissors_dynamic<I>(mut self, viewports: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Viewport>,
|
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.
|
/// Sample shading is disabled by default.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `min_fract` is not between 0.0 and 1.0.
|
/// - Panics if `min_fract` is not between 0.0 and 1.0.
|
||||||
///
|
|
||||||
#[deprecated(since = "0.27.0", note = "Use `multisample_state` instead")]
|
#[deprecated(since = "0.27.0", note = "Use `multisample_state` instead")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sample_shading_enabled(mut self, min_fract: f32) -> Self {
|
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")]
|
#[deprecated(since = "0.27.0", note = "Use `color_blend_state` instead")]
|
||||||
#[inline]
|
|
||||||
pub fn blend_individual<I>(mut self, blend: I) -> Self
|
pub fn blend_individual<I>(mut self, blend: I) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = AttachmentBlend>,
|
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.
|
/// Sets the render pass subpass to use.
|
||||||
#[inline]
|
|
||||||
pub fn render_pass(self, render_pass: impl Into<PipelineRenderPassType>) -> Self {
|
pub fn render_pass(self, render_pass: impl Into<PipelineRenderPassType>) -> Self {
|
||||||
GraphicsPipelineBuilder {
|
GraphicsPipelineBuilder {
|
||||||
render_pass: Some(render_pass.into()),
|
render_pass: Some(render_pass.into()),
|
||||||
|
@ -197,23 +197,21 @@ pub enum GraphicsPipelineCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for GraphicsPipelineCreationError {
|
impl Error for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
Self::PipelineLayoutCreationError(ref err) => Some(err),
|
Self::PipelineLayoutCreationError(err) => Some(err),
|
||||||
Self::IncompatiblePipelineLayout(ref err) => Some(err),
|
Self::IncompatiblePipelineLayout(err) => Some(err),
|
||||||
Self::ShaderStagesMismatch(ref err) => Some(err),
|
Self::ShaderStagesMismatch(err) => Some(err),
|
||||||
Self::IncompatibleVertexDefinition(ref err) => Some(err),
|
Self::IncompatibleVertexDefinition(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for GraphicsPipelineCreationError {
|
impl Display for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -222,7 +220,6 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::ColorAttachmentFormatBlendNotSupported { attachment_index } => write!(
|
Self::ColorAttachmentFormatBlendNotSupported { attachment_index } => write!(
|
||||||
f,
|
f,
|
||||||
"color attachment {} has a format that does not support blending",
|
"color attachment {} has a format that does not support blending",
|
||||||
@ -243,7 +240,8 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
),
|
),
|
||||||
Self::FragmentShaderRenderPassIncompatible => write!(
|
Self::FragmentShaderRenderPassIncompatible => write!(
|
||||||
f,
|
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!(
|
Self::IncompatiblePipelineLayout(_) => write!(
|
||||||
f,
|
f,
|
||||||
@ -251,7 +249,8 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
),
|
),
|
||||||
Self::IncompatibleSpecializationConstants => write!(
|
Self::IncompatibleSpecializationConstants => write!(
|
||||||
f,
|
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!(
|
Self::IncompatibleVertexDefinition(_) => write!(
|
||||||
f,
|
f,
|
||||||
@ -259,19 +258,21 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
),
|
),
|
||||||
Self::InvalidPrimitiveTopology => write!(
|
Self::InvalidPrimitiveTopology => write!(
|
||||||
f,
|
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!(
|
Self::InvalidNumPatchControlPoints => write!(
|
||||||
f,
|
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!(
|
Self::MaxDiscardRectanglesExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the maximum number of discard rectangles has been exceeded",
|
"the maximum number of discard rectangles has been exceeded",
|
||||||
),
|
),
|
||||||
Self::MaxMultiviewViewCountExceeded { .. } => {
|
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!(
|
Self::MaxVertexAttribDivisorExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the maximum value for the instance rate divisor has been exceeded",
|
"the maximum value for the instance rate divisor has been exceeded",
|
||||||
@ -284,29 +285,29 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
f,
|
f,
|
||||||
"the maximum offset for a vertex attribute has been exceeded",
|
"the maximum offset for a vertex attribute has been exceeded",
|
||||||
),
|
),
|
||||||
Self::MaxVertexInputBindingsExceeded { .. } => write!(
|
Self::MaxVertexInputBindingsExceeded { .. } => {
|
||||||
f,
|
write!(f, "the maximum number of vertex sources has been exceeded")
|
||||||
"the maximum number of vertex sources has been exceeded",
|
}
|
||||||
),
|
|
||||||
Self::MaxVertexInputBindingStrideExceeded { .. } => write!(
|
Self::MaxVertexInputBindingStrideExceeded { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the maximum stride value for vertex input (ie. the distance between two vertex elements) 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::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!(
|
Self::MismatchBlendingAttachmentsCount => write!(
|
||||||
f,
|
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!(
|
Self::MultisampleRasterizationSamplesMismatch => write!(
|
||||||
f,
|
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!(
|
Self::NoDepthAttachment => write!(
|
||||||
f,
|
f,
|
||||||
@ -316,30 +317,25 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
f,
|
f,
|
||||||
"the stencil attachment of the render pass does not match the stencil test",
|
"the stencil attachment of the render pass does not match the stencil test",
|
||||||
),
|
),
|
||||||
Self::OomError(_) => write!(
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
f,
|
Self::DescriptorSetLayoutCreationError(_) => {
|
||||||
"not enough memory available",
|
write!(f, "error while creating a descriptor set layout object")
|
||||||
),
|
}
|
||||||
Self::DescriptorSetLayoutCreationError(_) => write!(
|
Self::PipelineLayoutCreationError(_) => {
|
||||||
f,
|
write!(f, "error while creating the pipeline layout object")
|
||||||
"error while creating a descriptor set layout object",
|
}
|
||||||
),
|
|
||||||
Self::PipelineLayoutCreationError(_) => write!(
|
|
||||||
f,
|
|
||||||
"error while creating the pipeline layout object",
|
|
||||||
),
|
|
||||||
Self::ShaderStagesMismatch(_) => write!(
|
Self::ShaderStagesMismatch(_) => write!(
|
||||||
f,
|
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!(
|
Self::StencilAttachmentFormatUsageNotSupported => write!(
|
||||||
f,
|
f,
|
||||||
"the stencil attachment has a format that does not support that usage",
|
"the stencil attachment has a format that does not support that usage",
|
||||||
),
|
),
|
||||||
Self::StrictLinesNotSupported => write!(
|
Self::StrictLinesNotSupported => {
|
||||||
f,
|
write!(f, "the strict_lines device property was false")
|
||||||
"the strict_lines device property was false",
|
}
|
||||||
),
|
|
||||||
Self::TopologyNotMatchingGeometryShader => write!(
|
Self::TopologyNotMatchingGeometryShader => write!(
|
||||||
f,
|
f,
|
||||||
"the primitives topology does not match what the geometry shader expects",
|
"the primitives topology does not match what the geometry shader expects",
|
||||||
@ -350,77 +346,69 @@ impl Display for GraphicsPipelineCreationError {
|
|||||||
attribute_type,
|
attribute_type,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
location, shader_type, attribute_type,
|
||||||
),
|
),
|
||||||
Self::VertexInputAttributeInvalidBinding { location, binding } => write!(
|
Self::VertexInputAttributeInvalidBinding { location, binding } => write!(
|
||||||
f,
|
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,
|
binding, location,
|
||||||
),
|
),
|
||||||
Self::VertexInputAttributeMissing { location } => write!(
|
Self::VertexInputAttributeMissing { location } => write!(
|
||||||
f,
|
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,
|
location,
|
||||||
),
|
),
|
||||||
Self::VertexInputAttributeUnsupportedFormat { location, format } => write!(
|
Self::VertexInputAttributeUnsupportedFormat { location, format } => write!(
|
||||||
f,
|
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,
|
format, location,
|
||||||
),
|
),
|
||||||
Self::ViewportBoundsExceeded => write!(
|
Self::ViewportBoundsExceeded => write!(
|
||||||
f,
|
f,
|
||||||
"the minimum or maximum bounds of viewports have been exceeded",
|
"the minimum or maximum bounds of viewports have been exceeded",
|
||||||
),
|
),
|
||||||
Self::WrongShaderType => write!(
|
Self::WrongShaderType => write!(f, "the wrong type of shader has been passed"),
|
||||||
f,
|
Self::WrongStencilState => write!(f, "the requested stencil test is invalid"),
|
||||||
"the wrong type of shader has been passed",
|
|
||||||
),
|
|
||||||
Self::WrongStencilState => write!(
|
|
||||||
f,
|
|
||||||
"the requested stencil test is invalid",
|
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for GraphicsPipelineCreationError {
|
impl From<OomError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> GraphicsPipelineCreationError {
|
fn from(err: OomError) -> GraphicsPipelineCreationError {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<DescriptorSetLayoutCreationError> for GraphicsPipelineCreationError {
|
impl From<DescriptorSetLayoutCreationError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: DescriptorSetLayoutCreationError) -> Self {
|
fn from(err: DescriptorSetLayoutCreationError) -> Self {
|
||||||
Self::DescriptorSetLayoutCreationError(err)
|
Self::DescriptorSetLayoutCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PipelineLayoutCreationError> for GraphicsPipelineCreationError {
|
impl From<PipelineLayoutCreationError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: PipelineLayoutCreationError) -> Self {
|
fn from(err: PipelineLayoutCreationError) -> Self {
|
||||||
Self::PipelineLayoutCreationError(err)
|
Self::PipelineLayoutCreationError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError {
|
impl From<PipelineLayoutSupersetError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: PipelineLayoutSupersetError) -> Self {
|
fn from(err: PipelineLayoutSupersetError) -> Self {
|
||||||
Self::IncompatiblePipelineLayout(err)
|
Self::IncompatiblePipelineLayout(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError {
|
impl From<IncompatibleVertexDefinitionError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: IncompatibleVertexDefinitionError) -> Self {
|
fn from(err: IncompatibleVertexDefinitionError) -> Self {
|
||||||
Self::IncompatibleVertexDefinition(err)
|
Self::IncompatibleVertexDefinition(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for GraphicsPipelineCreationError {
|
impl From<VulkanError> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
@ -431,7 +419,6 @@ impl From<VulkanError> for GraphicsPipelineCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for GraphicsPipelineCreationError {
|
impl From<RequirementNotMet> for GraphicsPipelineCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -183,7 +183,6 @@ pub enum PrimitiveTopologyClass {
|
|||||||
|
|
||||||
impl PrimitiveTopologyClass {
|
impl PrimitiveTopologyClass {
|
||||||
/// Returns a representative example of this topology class.
|
/// Returns a representative example of this topology class.
|
||||||
#[inline]
|
|
||||||
pub(crate) fn example(&self) -> PrimitiveTopology {
|
pub(crate) fn example(&self) -> PrimitiveTopology {
|
||||||
match self {
|
match self {
|
||||||
Self::Point => PrimitiveTopology::PointList,
|
Self::Point => PrimitiveTopology::PointList,
|
||||||
|
@ -123,6 +123,7 @@ pub struct GraphicsPipeline {
|
|||||||
impl GraphicsPipeline {
|
impl GraphicsPipeline {
|
||||||
/// Starts the building process of a graphics pipeline. Returns a builder object that you can
|
/// Starts the building process of a graphics pipeline. Returns a builder object that you can
|
||||||
/// fill with the various parameters.
|
/// fill with the various parameters.
|
||||||
|
#[inline]
|
||||||
pub fn start() -> GraphicsPipelineBuilder<
|
pub fn start() -> GraphicsPipelineBuilder<
|
||||||
'static,
|
'static,
|
||||||
'static,
|
'static,
|
||||||
@ -155,7 +156,8 @@ impl GraphicsPipeline {
|
|||||||
///
|
///
|
||||||
/// `None` is returned if the pipeline does not contain this shader.
|
/// `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
|
// TODO: ^ implement and make this public
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn shader(&self, stage: ShaderStage) -> Option<()> {
|
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
|
/// `None` is returned if the pipeline does not contain this state. Previously set dynamic
|
||||||
/// state is not disturbed when binding it.
|
/// state is not disturbed when binding it.
|
||||||
|
#[inline]
|
||||||
pub fn dynamic_state(&self, state: DynamicState) -> Option<bool> {
|
pub fn dynamic_state(&self, state: DynamicState) -> Option<bool> {
|
||||||
self.dynamic_state.get(&state).copied()
|
self.dynamic_state.get(&state).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns all potentially dynamic states in the pipeline, and whether they are dynamic or not.
|
/// 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)> + '_ {
|
pub fn dynamic_states(&self) -> impl ExactSizeIterator<Item = (DynamicState, bool)> + '_ {
|
||||||
self.dynamic_state.iter().map(|(k, v)| (*k, *v))
|
self.dynamic_state.iter().map(|(k, v)| (*k, *v))
|
||||||
}
|
}
|
||||||
@ -265,7 +269,6 @@ unsafe impl DeviceOwned for GraphicsPipeline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for GraphicsPipeline {
|
impl Debug for GraphicsPipeline {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(f, "<Vulkan graphics pipeline {:?}>", self.handle)
|
write!(f, "<Vulkan graphics pipeline {:?}>", self.handle)
|
||||||
}
|
}
|
||||||
@ -300,7 +303,6 @@ impl PartialEq for GraphicsPipeline {
|
|||||||
impl Eq for GraphicsPipeline {}
|
impl Eq for GraphicsPipeline {}
|
||||||
|
|
||||||
impl Hash for GraphicsPipeline {
|
impl Hash for GraphicsPipeline {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device.hash(state);
|
self.device.hash(state);
|
||||||
|
@ -298,6 +298,7 @@ vulkan_enum! {
|
|||||||
|
|
||||||
impl Default for LineRasterizationMode {
|
impl Default for LineRasterizationMode {
|
||||||
/// Returns `LineRasterizationMode::Default`.
|
/// Returns `LineRasterizationMode::Default`.
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Default
|
Self::Default
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,7 @@ impl TessellationState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the number of patch control points to dynamic.
|
/// Sets the number of patch control points to dynamic.
|
||||||
|
#[inline]
|
||||||
pub fn patch_control_points_dynamic(mut self) -> Self {
|
pub fn patch_control_points_dynamic(mut self) -> Self {
|
||||||
self.patch_control_points = StateMode::Dynamic;
|
self.patch_control_points = StateMode::Dynamic;
|
||||||
self
|
self
|
||||||
|
@ -43,7 +43,6 @@ impl Debug for VertexBuffer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VertexBuffer> for VertexInputBindingDescription {
|
impl From<VertexBuffer> for VertexInputBindingDescription {
|
||||||
#[inline]
|
|
||||||
fn from(val: VertexBuffer) -> Self {
|
fn from(val: VertexBuffer) -> Self {
|
||||||
Self {
|
Self {
|
||||||
stride: val.stride,
|
stride: val.stride,
|
||||||
@ -54,6 +53,7 @@ impl From<VertexBuffer> for VertexInputBindingDescription {
|
|||||||
|
|
||||||
impl BuffersDefinition {
|
impl BuffersDefinition {
|
||||||
/// Constructs a new definition.
|
/// Constructs a new definition.
|
||||||
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
BuffersDefinition(Vec::new())
|
BuffersDefinition(Vec::new())
|
||||||
}
|
}
|
||||||
@ -65,6 +65,7 @@ impl BuffersDefinition {
|
|||||||
stride: mem::size_of::<V>() as u32,
|
stride: mem::size_of::<V>() as u32,
|
||||||
input_rate: VertexInputRate::Vertex,
|
input_rate: VertexInputRate::Vertex,
|
||||||
});
|
});
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,31 +76,34 @@ impl BuffersDefinition {
|
|||||||
stride: mem::size_of::<V>() as u32,
|
stride: mem::size_of::<V>() as u32,
|
||||||
input_rate: VertexInputRate::Instance { divisor: 1 },
|
input_rate: VertexInputRate::Instance { divisor: 1 },
|
||||||
});
|
});
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new instance buffer containing elements of type `V` to the definition, with the
|
/// Adds a new instance buffer containing elements of type `V` to the definition, with the
|
||||||
/// specified input rate divisor.
|
/// specified input rate divisor.
|
||||||
///
|
///
|
||||||
/// This requires the
|
/// This requires the [`vertex_attribute_instance_rate_divisor`] feature has been enabled on
|
||||||
/// [`vertex_attribute_instance_rate_divisor`](crate::device::Features::vertex_attribute_instance_rate_divisor)
|
/// the device, unless `divisor` is 1.
|
||||||
/// feature has been enabled on the device, unless `divisor` is 1.
|
|
||||||
///
|
///
|
||||||
/// `divisor` can be 0 if the
|
/// `divisor` can be 0 if the [`vertex_attribute_instance_rate_zero_divisor`] feature is also
|
||||||
/// [`vertex_attribute_instance_rate_zero_divisor`](crate::device::Features::vertex_attribute_instance_rate_zero_divisor)
|
/// enabled. This means that every vertex will use the same vertex and instance data.
|
||||||
/// 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 {
|
pub fn instance_with_divisor<V: Vertex>(mut self, divisor: u32) -> Self {
|
||||||
self.0.push(VertexBuffer {
|
self.0.push(VertexBuffer {
|
||||||
info_fn: V::member,
|
info_fn: V::member,
|
||||||
stride: mem::size_of::<V>() as u32,
|
stride: mem::size_of::<V>() as u32,
|
||||||
input_rate: VertexInputRate::Instance { divisor },
|
input_rate: VertexInputRate::Instance { divisor },
|
||||||
});
|
});
|
||||||
|
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl VertexDefinition for BuffersDefinition {
|
unsafe impl VertexDefinition for BuffersDefinition {
|
||||||
|
#[inline]
|
||||||
fn definition(
|
fn definition(
|
||||||
&self,
|
&self,
|
||||||
interface: &ShaderInterface,
|
interface: &ShaderInterface,
|
||||||
|
@ -25,14 +25,12 @@ impl VertexBuffersCollection for () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BufferAccessObject> VertexBuffersCollection for T {
|
impl<T: BufferAccessObject> VertexBuffersCollection for T {
|
||||||
#[inline]
|
|
||||||
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
||||||
vec![self.as_buffer_access_object()]
|
vec![self.as_buffer_access_object()]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: BufferAccessObject> VertexBuffersCollection for Vec<T> {
|
impl<T: BufferAccessObject> VertexBuffersCollection for Vec<T> {
|
||||||
#[inline]
|
|
||||||
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
||||||
self.into_iter()
|
self.into_iter()
|
||||||
.map(|src| src.as_buffer_access_object())
|
.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] {
|
impl<T: BufferAccessObject, const N: usize> VertexBuffersCollection for [T; N] {
|
||||||
#[inline]
|
|
||||||
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
fn into_vec(self) -> Vec<Arc<dyn BufferAccess>> {
|
||||||
self.into_iter()
|
self.into_iter()
|
||||||
.map(|src| src.as_buffer_access_object())
|
.map(|src| src.as_buffer_access_object())
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! The `Vertex` trait is unsafe, but can be implemented on a struct with the `impl_vertex!`
|
//! The `Vertex` trait is unsafe, but can be implemented on a struct with the `impl_vertex!`
|
||||||
//! macro.
|
//! macro.
|
||||||
//!
|
//!
|
||||||
//! # Example
|
//! # Examples
|
||||||
//!
|
//!
|
||||||
//! ```ignore // TODO:
|
//! ```ignore // TODO:
|
||||||
//! # #[macro_use] extern crate vulkano
|
//! # #[macro_use] extern crate vulkano
|
||||||
@ -40,11 +40,11 @@
|
|||||||
//!
|
//!
|
||||||
//! let usage = BufferUsage {
|
//! let usage = BufferUsage {
|
||||||
//! vertex_buffer: true,
|
//! vertex_buffer: true,
|
||||||
//! .. BufferUsage::empty()
|
//! ..BufferUsage::empty()
|
||||||
//! };
|
//! };
|
||||||
//!
|
//!
|
||||||
//! let vertex_buffer = BufferAccess::<[Vertex], _>::array(&device, 128, &usage, HostVisible, &queue)
|
//! let vertex_buffer = BufferAccess::<[Vertex], _>::array(&device, 128, &usage, HostVisible, &queue)
|
||||||
//! .expect("failed to create buffer");
|
//! .expect("failed to create buffer");
|
||||||
//!
|
//!
|
||||||
//! // TODO: finish example
|
//! // TODO: finish example
|
||||||
//! # }
|
//! # }
|
||||||
@ -103,11 +103,10 @@ pub enum IncompatibleVertexDefinitionError {
|
|||||||
impl Error for IncompatibleVertexDefinitionError {}
|
impl Error for IncompatibleVertexDefinitionError {}
|
||||||
|
|
||||||
impl Display for IncompatibleVertexDefinitionError {
|
impl Display for IncompatibleVertexDefinitionError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
IncompatibleVertexDefinitionError::MissingAttribute { .. } => {
|
IncompatibleVertexDefinitionError::MissingAttribute { .. } => {
|
||||||
write!(f, "an attribute is missing",)
|
write!(f, "an attribute is missing")
|
||||||
}
|
}
|
||||||
IncompatibleVertexDefinitionError::FormatMismatch { .. } => {
|
IncompatibleVertexDefinitionError::FormatMismatch { .. } => {
|
||||||
write!(f, "the format of an attribute does not match")
|
write!(f, "the format of an attribute does not match")
|
||||||
|
@ -10,21 +10,20 @@
|
|||||||
use crate::pipeline::graphics::vertex_input::VertexMemberTy;
|
use crate::pipeline::graphics::vertex_input::VertexMemberTy;
|
||||||
|
|
||||||
/// Implements the `Vertex` trait on a struct.
|
/// Implements the `Vertex` trait on a struct.
|
||||||
///# Example
|
|
||||||
///
|
///
|
||||||
///```
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
/// # use bytemuck::{Zeroable, Pod};
|
/// # use bytemuck::{Zeroable, Pod};
|
||||||
|
/// #[repr(C)]
|
||||||
|
/// #[derive(Clone, Copy, Debug, Default, Zeroable, Pod)]
|
||||||
|
/// struct Vertex{
|
||||||
|
/// position: [f32; 3],
|
||||||
|
/// color: [f32; 4],
|
||||||
|
/// }
|
||||||
///
|
///
|
||||||
///#[repr(C)]
|
/// vulkano::impl_vertex!(Vertex, position, color);
|
||||||
///#[derive(Clone, Copy, Debug, Default, Zeroable, Pod)]
|
/// ```
|
||||||
///struct Vertex{
|
|
||||||
/// position: [f32; 3],
|
|
||||||
/// color: [f32; 4]
|
|
||||||
///}
|
|
||||||
///
|
|
||||||
///vulkano::impl_vertex!(Vertex, position, color);
|
|
||||||
///
|
|
||||||
///```
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! impl_vertex {
|
macro_rules! impl_vertex {
|
||||||
($out:ty $(, $member:ident)*) => (
|
($out:ty $(, $member:ident)*) => (
|
||||||
@ -128,7 +127,6 @@ unsafe impl<T> VertexMember for (T,)
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
<T as VertexMember>::format()
|
<T as VertexMember>::format()
|
||||||
}
|
}
|
||||||
@ -138,7 +136,6 @@ unsafe impl<T> VertexMember for (T, T)
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 2)
|
(ty, sz * 2)
|
||||||
@ -149,7 +146,6 @@ unsafe impl<T> VertexMember for (T, T, T)
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 3)
|
(ty, sz * 3)
|
||||||
@ -160,7 +156,6 @@ unsafe impl<T> VertexMember for (T, T, T, T)
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 4)
|
(ty, sz * 4)
|
||||||
@ -172,7 +167,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector1<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
<T as VertexMember>::format()
|
<T as VertexMember>::format()
|
||||||
}
|
}
|
||||||
@ -183,7 +177,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector2<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 2)
|
(ty, sz * 2)
|
||||||
@ -195,7 +188,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector3<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 3)
|
(ty, sz * 3)
|
||||||
@ -207,7 +199,6 @@ unsafe impl<T> VertexMember for nalgebra::Vector4<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 4)
|
(ty, sz * 4)
|
||||||
@ -219,7 +210,6 @@ unsafe impl<T> VertexMember for nalgebra::Point1<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember + nalgebra::Scalar,
|
T: VertexMember + nalgebra::Scalar,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
<T as VertexMember>::format()
|
<T as VertexMember>::format()
|
||||||
}
|
}
|
||||||
@ -230,7 +220,6 @@ unsafe impl<T> VertexMember for nalgebra::Point2<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember + nalgebra::Scalar,
|
T: VertexMember + nalgebra::Scalar,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 2)
|
(ty, sz * 2)
|
||||||
@ -242,7 +231,6 @@ unsafe impl<T> VertexMember for nalgebra::Point3<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember + nalgebra::Scalar,
|
T: VertexMember + nalgebra::Scalar,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 3)
|
(ty, sz * 3)
|
||||||
@ -254,7 +242,6 @@ unsafe impl<T> VertexMember for nalgebra::Point4<T>
|
|||||||
where
|
where
|
||||||
T: VertexMember + nalgebra::Scalar,
|
T: VertexMember + nalgebra::Scalar,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * 4)
|
(ty, sz * 4)
|
||||||
@ -267,7 +254,6 @@ macro_rules! impl_vm_array {
|
|||||||
where
|
where
|
||||||
T: VertexMember,
|
T: VertexMember,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn format() -> (VertexMemberTy, usize) {
|
fn format() -> (VertexMemberTy, usize) {
|
||||||
let (ty, sz) = <T as VertexMember>::format();
|
let (ty, sz) = <T as VertexMember>::format();
|
||||||
(ty, sz * $sz)
|
(ty, sz * $sz)
|
||||||
|
@ -143,7 +143,6 @@ impl VertexInputState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets all bindings.
|
/// Sets all bindings.
|
||||||
#[inline]
|
|
||||||
pub fn bindings(
|
pub fn bindings(
|
||||||
mut self,
|
mut self,
|
||||||
bindings: impl IntoIterator<Item = (u32, VertexInputBindingDescription)>,
|
bindings: impl IntoIterator<Item = (u32, VertexInputBindingDescription)>,
|
||||||
@ -164,7 +163,6 @@ impl VertexInputState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Sets all attributes.
|
/// Sets all attributes.
|
||||||
#[inline]
|
|
||||||
pub fn attributes(
|
pub fn attributes(
|
||||||
mut self,
|
mut self,
|
||||||
attributes: impl IntoIterator<Item = (u32, VertexInputAttributeDescription)>,
|
attributes: impl IntoIterator<Item = (u32, VertexInputAttributeDescription)>,
|
||||||
@ -208,14 +206,14 @@ pub enum VertexInputRate {
|
|||||||
/// Each element of the source corresponds to an instance.
|
/// Each element of the source corresponds to an instance.
|
||||||
///
|
///
|
||||||
/// `divisor` indicates how many consecutive instances will use the same instance buffer data.
|
/// `divisor` indicates how many consecutive instances will use the same instance buffer data.
|
||||||
/// This value must be 1, unless the
|
/// This value must be 1, unless the [`vertex_attribute_instance_rate_divisor`] feature has
|
||||||
/// [`vertex_attribute_instance_rate_divisor`](crate::device::Features::vertex_attribute_instance_rate_divisor)
|
/// been enabled on the device.
|
||||||
/// feature has been enabled on the device.
|
|
||||||
///
|
///
|
||||||
/// `divisor` can be 0 if the
|
/// `divisor` can be 0 if the [`vertex_attribute_instance_rate_zero_divisor`] feature is also
|
||||||
/// [`vertex_attribute_instance_rate_zero_divisor`](crate::device::Features::vertex_attribute_instance_rate_zero_divisor)
|
/// enabled. This means that every vertex will use the same vertex and instance data.
|
||||||
/// 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 },
|
Instance { divisor: u32 },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,6 @@ impl ViewportState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a `ViewportState` with fixed state from the given viewports and scissors.
|
/// Creates a `ViewportState` with fixed state from the given viewports and scissors.
|
||||||
#[inline]
|
|
||||||
pub fn viewport_fixed_scissor_fixed(
|
pub fn viewport_fixed_scissor_fixed(
|
||||||
data: impl IntoIterator<Item = (Viewport, Scissor)>,
|
data: impl IntoIterator<Item = (Viewport, Scissor)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -131,7 +130,6 @@ impl ViewportState {
|
|||||||
|
|
||||||
/// Creates a `ViewportState` with fixed state from the given viewports, and matching scissors
|
/// Creates a `ViewportState` with fixed state from the given viewports, and matching scissors
|
||||||
/// that cover the whole viewport.
|
/// that cover the whole viewport.
|
||||||
#[inline]
|
|
||||||
pub fn viewport_fixed_scissor_irrelevant(data: impl IntoIterator<Item = Viewport>) -> Self {
|
pub fn viewport_fixed_scissor_irrelevant(data: impl IntoIterator<Item = Viewport>) -> Self {
|
||||||
Self::Fixed {
|
Self::Fixed {
|
||||||
data: data
|
data: data
|
||||||
@ -174,6 +172,7 @@ impl ViewportState {
|
|||||||
/// Returns the number of viewports and scissors.
|
/// Returns the number of viewports and scissors.
|
||||||
///
|
///
|
||||||
/// `None` is returned if both `viewport_count_dynamic` and `scissor_count_dynamic` are `true`.
|
/// `None` is returned if both `viewport_count_dynamic` and `scissor_count_dynamic` are `true`.
|
||||||
|
#[inline]
|
||||||
pub fn count(&self) -> Option<u32> {
|
pub fn count(&self) -> Option<u32> {
|
||||||
Some(match *self {
|
Some(match *self {
|
||||||
ViewportState::Fixed { ref data } => data.len() as u32,
|
ViewportState::Fixed { ref data } => data.len() as u32,
|
||||||
|
@ -531,6 +531,7 @@ impl PipelineLayout {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::PipelineLayout,
|
handle: ash::vk::PipelineLayout,
|
||||||
@ -587,6 +588,7 @@ impl PipelineLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether `self` is compatible with `other` for the given number of sets.
|
/// 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 {
|
pub fn is_compatible_with(&self, other: &PipelineLayout, num_sets: u32) -> bool {
|
||||||
let num_sets = num_sets as usize;
|
let num_sets = num_sets as usize;
|
||||||
assert!(num_sets >= self.set_layouts.len());
|
assert!(num_sets >= self.set_layouts.len());
|
||||||
@ -680,6 +682,7 @@ impl Drop for PipelineLayout {
|
|||||||
unsafe impl VulkanObject for PipelineLayout {
|
unsafe impl VulkanObject for PipelineLayout {
|
||||||
type Object = ash::vk::PipelineLayout;
|
type Object = ash::vk::PipelineLayout;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
fn internal_object(&self) -> Self::Object {
|
fn internal_object(&self) -> Self::Object {
|
||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
@ -702,7 +705,6 @@ impl PartialEq for PipelineLayout {
|
|||||||
impl Eq for PipelineLayout {}
|
impl Eq for PipelineLayout {}
|
||||||
|
|
||||||
impl Hash for PipelineLayout {
|
impl Hash for PipelineLayout {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -822,21 +824,18 @@ pub enum PipelineLayoutCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for PipelineLayoutCreationError {
|
impl Error for PipelineLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PipelineLayoutCreationError {
|
impl Display for PipelineLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -845,90 +844,167 @@ impl Display for PipelineLayoutCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::MaxBoundDescriptorSetsExceeded {
|
||||||
Self::MaxBoundDescriptorSetsExceeded { provided, max_supported } => write!(
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetSamplersExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetSamplersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetUniformBuffersExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetUniformBuffersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetUniformBuffersDynamicExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetUniformBuffersDynamicExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetStorageBuffersExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetStorageBuffersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetStorageBuffersDynamicExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetStorageBuffersDynamicExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetSampledImagesExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetSampledImagesExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetStorageImagesExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetStorageImagesExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxDescriptorSetInputAttachmentsExceeded { provided, max_supported } => write!(
|
Self::MaxDescriptorSetInputAttachmentsExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageResourcesExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageResourcesExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorSamplersExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorSamplersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorUniformBuffersExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorUniformBuffersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorStorageBuffersExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorStorageBuffersExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorSampledImagesExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorSampledImagesExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorStorageImagesExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorStorageImagesExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPerStageDescriptorInputAttachmentsExceeded { provided, max_supported } => write!(
|
Self::MaxPerStageDescriptorInputAttachmentsExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::MaxPushConstantsSizeExceeded { provided, max_supported } => write!(
|
Self::MaxPushConstantsSizeExceeded {
|
||||||
|
provided,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::PushConstantRangesStageMultiple => write!(
|
Self::PushConstantRangesStageMultiple => write!(
|
||||||
@ -937,21 +1013,19 @@ impl Display for PipelineLayoutCreationError {
|
|||||||
),
|
),
|
||||||
Self::SetLayoutsPushDescriptorMultiple => write!(
|
Self::SetLayoutsPushDescriptorMultiple => write!(
|
||||||
f,
|
f,
|
||||||
"multiple elements of `set_layouts` have `push_descriptor` enabled"
|
"multiple elements of `set_layouts` have `push_descriptor` enabled",
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for PipelineLayoutCreationError {
|
impl From<OomError> for PipelineLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> PipelineLayoutCreationError {
|
fn from(err: OomError) -> PipelineLayoutCreationError {
|
||||||
PipelineLayoutCreationError::OomError(err)
|
PipelineLayoutCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for PipelineLayoutCreationError {
|
impl From<VulkanError> for PipelineLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> PipelineLayoutCreationError {
|
fn from(err: VulkanError) -> PipelineLayoutCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -966,7 +1040,6 @@ impl From<VulkanError> for PipelineLayoutCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for PipelineLayoutCreationError {
|
impl From<RequirementNotMet> for PipelineLayoutCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -994,55 +1067,53 @@ pub enum PipelineLayoutSupersetError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for PipelineLayoutSupersetError {
|
impl Error for PipelineLayoutSupersetError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { ref error, .. } => {
|
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { error, .. } => Some(error),
|
||||||
Some(error)
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PipelineLayoutSupersetError {
|
impl Display for PipelineLayoutSupersetError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
PipelineLayoutSupersetError::DescriptorRequirementsNotMet { set_num, binding_num, .. } => write!(
|
PipelineLayoutSupersetError::DescriptorRequirementsNotMet {
|
||||||
|
set_num,
|
||||||
|
binding_num,
|
||||||
|
..
|
||||||
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the descriptor at set {} binding {} does not meet the requirements",
|
"the descriptor at set {} binding {} does not meet the requirements",
|
||||||
set_num, binding_num
|
set_num, binding_num,
|
||||||
),
|
),
|
||||||
PipelineLayoutSupersetError::DescriptorMissing {
|
PipelineLayoutSupersetError::DescriptorMissing {
|
||||||
set_num,
|
set_num,
|
||||||
binding_num,
|
binding_num,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"a descriptor at set {} binding {} is required by the shaders, but is missing from the pipeline layout",
|
"a descriptor at set {} binding {} is required by the shaders, but is missing from \
|
||||||
set_num, binding_num
|
the pipeline layout",
|
||||||
|
set_num, binding_num,
|
||||||
),
|
),
|
||||||
PipelineLayoutSupersetError::PushConstantRange {
|
PipelineLayoutSupersetError::PushConstantRange {
|
||||||
first_range,
|
first_range,
|
||||||
second_range,
|
second_range,
|
||||||
} => {
|
} => {
|
||||||
writeln!(
|
writeln!(f, "our range did not completely encompass the other range")?;
|
||||||
f,
|
|
||||||
"our range did not completely encompass the other range"
|
|
||||||
)?;
|
|
||||||
writeln!(f, " our stages: {:?}", first_range.stages)?;
|
writeln!(f, " our stages: {:?}", first_range.stages)?;
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
" our range: {} - {}",
|
" our range: {} - {}",
|
||||||
first_range.offset,
|
first_range.offset,
|
||||||
first_range.offset + first_range.size
|
first_range.offset + first_range.size,
|
||||||
)?;
|
)?;
|
||||||
writeln!(f, " other stages: {:?}", second_range.stages)?;
|
writeln!(f, " other stages: {:?}", second_range.stages)?;
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
" other range: {} - {}",
|
" other range: {} - {}",
|
||||||
second_range.offset,
|
second_range.offset,
|
||||||
second_range.offset + second_range.size
|
second_range.offset + second_range.size,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +269,6 @@ pub enum StateMode<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<Option<T>> for StateMode<T> {
|
impl<T> From<Option<T>> for StateMode<T> {
|
||||||
#[inline]
|
|
||||||
fn from(val: Option<T>) -> Self {
|
fn from(val: Option<T>) -> Self {
|
||||||
match val {
|
match val {
|
||||||
Some(x) => StateMode::Fixed(x),
|
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> {
|
impl<T> From<StateMode<T>> for Option<T> {
|
||||||
#[inline]
|
|
||||||
fn from(val: StateMode<T>) -> Self {
|
fn from(val: StateMode<T>) -> Self {
|
||||||
match val {
|
match val {
|
||||||
StateMode::Fixed(x) => Some(x),
|
StateMode::Fixed(x) => Some(x),
|
||||||
|
@ -110,6 +110,7 @@ impl QueryPool {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::QueryPool,
|
handle: ash::vk::QueryPool,
|
||||||
@ -120,6 +121,7 @@ impl QueryPool {
|
|||||||
query_count,
|
query_count,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = create_info;
|
} = create_info;
|
||||||
|
|
||||||
Arc::new(QueryPool {
|
Arc::new(QueryPool {
|
||||||
handle,
|
handle,
|
||||||
device,
|
device,
|
||||||
@ -152,9 +154,9 @@ impl QueryPool {
|
|||||||
|
|
||||||
/// Returns a reference to a range of queries, or `None` if out of range.
|
/// 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]
|
#[inline]
|
||||||
pub fn queries_range(&self, range: Range<u32>) -> Option<QueriesRange<'_>> {
|
pub fn queries_range(&self, range: Range<u32>) -> Option<QueriesRange<'_>> {
|
||||||
assert!(!range.is_empty());
|
assert!(!range.is_empty());
|
||||||
@ -203,7 +205,6 @@ impl PartialEq for QueryPool {
|
|||||||
impl Eq for QueryPool {}
|
impl Eq for QueryPool {}
|
||||||
|
|
||||||
impl Hash for QueryPool {
|
impl Hash for QueryPool {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -248,17 +249,15 @@ pub enum QueryPoolCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for QueryPoolCreationError {
|
impl Error for QueryPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
QueryPoolCreationError::OomError(ref err) => Some(err),
|
QueryPoolCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for QueryPoolCreationError {
|
impl Display for QueryPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
@ -267,7 +266,7 @@ impl Display for QueryPoolCreationError {
|
|||||||
QueryPoolCreationError::OomError(_) => "not enough memory available",
|
QueryPoolCreationError::OomError(_) => "not enough memory available",
|
||||||
QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled => {
|
QueryPoolCreationError::PipelineStatisticsQueryFeatureNotEnabled => {
|
||||||
"a pipeline statistics pool was requested but the corresponding feature \
|
"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 {
|
impl From<OomError> for QueryPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> QueryPoolCreationError {
|
fn from(err: OomError) -> QueryPoolCreationError {
|
||||||
QueryPoolCreationError::OomError(err)
|
QueryPoolCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for QueryPoolCreationError {
|
impl From<VulkanError> for QueryPoolCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> QueryPoolCreationError {
|
fn from(err: VulkanError) -> QueryPoolCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
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.
|
/// 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).
|
/// See also [`copy_query_pool_results`](crate::command_buffer::AutoCommandBufferBuilder::copy_query_pool_results).
|
||||||
|
#[inline]
|
||||||
pub fn get_results<T>(
|
pub fn get_results<T>(
|
||||||
&self,
|
&self,
|
||||||
destination: &mut [T],
|
destination: &mut [T],
|
||||||
@ -461,22 +459,19 @@ pub enum GetResultsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for GetResultsError {
|
impl Error for GetResultsError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for GetResultsError {
|
impl Display for GetResultsError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
|
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -485,7 +480,6 @@ impl Display for GetResultsError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::BufferTooSmall { .. } => write!(f, "the buffer is too small for the operation"),
|
Self::BufferTooSmall { .. } => write!(f, "the buffer is too small for the operation"),
|
||||||
Self::InvalidFlags => write!(
|
Self::InvalidFlags => write!(
|
||||||
f,
|
f,
|
||||||
@ -496,7 +490,6 @@ impl Display for GetResultsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for GetResultsError {
|
impl From<VulkanError> for GetResultsError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
||||||
@ -509,14 +502,12 @@ impl From<VulkanError> for GetResultsError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for GetResultsError {
|
impl From<OomError> for GetResultsError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for GetResultsError {
|
impl From<RequirementNotMet> for GetResultsError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -37,6 +37,7 @@ where
|
|||||||
V: Eq + Clone,
|
V: Eq + Clone,
|
||||||
{
|
{
|
||||||
/// Makes a new empty `RangeMap`.
|
/// Makes a new empty `RangeMap`.
|
||||||
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
RangeMap {
|
RangeMap {
|
||||||
btm: BTreeMap::new(),
|
btm: BTreeMap::new(),
|
||||||
@ -45,12 +46,14 @@ where
|
|||||||
|
|
||||||
/// Returns a reference to the value corresponding to the given key,
|
/// Returns a reference to the value corresponding to the given key,
|
||||||
/// if the key is covered by any range in the map.
|
/// if the key is covered by any range in the map.
|
||||||
|
#[inline]
|
||||||
pub fn get(&self, key: &K) -> Option<&V> {
|
pub fn get(&self, key: &K) -> Option<&V> {
|
||||||
self.get_key_value(key).map(|(_range, value)| value)
|
self.get_key_value(key).map(|(_range, value)| value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the range-value pair (as a pair of references) corresponding
|
/// 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.
|
/// 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)> {
|
pub fn get_key_value(&self, key: &K) -> Option<(&Range<K>, &V)> {
|
||||||
// The only stored range that could contain the given key is the
|
// 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.
|
// 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.
|
/// Returns `true` if any range in the map covers the specified key.
|
||||||
|
#[inline]
|
||||||
pub fn contains_key(&self, key: &K) -> bool {
|
pub fn contains_key(&self, key: &K) -> bool {
|
||||||
self.get(key).is_some()
|
self.get(key).is_some()
|
||||||
}
|
}
|
||||||
@ -88,6 +92,7 @@ where
|
|||||||
/// ordered by key range.
|
/// ordered by key range.
|
||||||
///
|
///
|
||||||
/// The iterator element type is `(&'a Range<K>, &'a V)`.
|
/// The iterator element type is `(&'a Range<K>, &'a V)`.
|
||||||
|
#[inline]
|
||||||
pub fn iter(&self) -> Iter<'_, K, V> {
|
pub fn iter(&self) -> Iter<'_, K, V> {
|
||||||
Iter {
|
Iter {
|
||||||
inner: self.btm.iter(),
|
inner: self.btm.iter(),
|
||||||
@ -98,6 +103,7 @@ where
|
|||||||
/// ordered by key range.
|
/// ordered by key range.
|
||||||
///
|
///
|
||||||
/// The iterator element type is `(&'a Range<K>, &'a mut V)`.
|
/// The iterator element type is `(&'a Range<K>, &'a mut V)`.
|
||||||
|
#[inline]
|
||||||
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
|
||||||
IterMut {
|
IterMut {
|
||||||
inner: self.btm.iter_mut(),
|
inner: self.btm.iter_mut(),
|
||||||
@ -767,6 +773,7 @@ pub struct RangeStartWrapper<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> RangeStartWrapper<T> {
|
impl<T> RangeStartWrapper<T> {
|
||||||
|
#[inline]
|
||||||
pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
|
pub fn new(range: Range<T>) -> RangeStartWrapper<T> {
|
||||||
RangeStartWrapper { range }
|
RangeStartWrapper { range }
|
||||||
}
|
}
|
||||||
|
@ -1577,21 +1577,18 @@ pub enum RenderPassCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for RenderPassCreationError {
|
impl Error for RenderPassCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
RenderPassCreationError::OomError(ref err) => Some(err),
|
RenderPassCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for RenderPassCreationError {
|
impl Display for RenderPassCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available",),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1600,63 +1597,88 @@ impl Display for RenderPassCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::AttachmentFirstUseLoadOpInvalid {
|
||||||
Self::AttachmentFirstUseLoadOpInvalid { attachment, first_use_subpass } => write!(
|
attachment,
|
||||||
|
first_use_subpass,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, first_use_subpass,
|
||||||
),
|
),
|
||||||
Self::AttachmentLayoutInvalid { attachment } => write!(
|
Self::AttachmentLayoutInvalid { attachment } => write!(
|
||||||
f,
|
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,
|
attachment,
|
||||||
),
|
),
|
||||||
Self::CorrelatedViewMasksMultiviewNotEnabled => write!(
|
Self::CorrelatedViewMasksMultiviewNotEnabled => write!(
|
||||||
f,
|
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!(
|
Self::CorrelatedViewMasksOverlapping => write!(
|
||||||
f,
|
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!(
|
Self::DependencyAccessNotSupportedByStages { dependency } => write!(
|
||||||
f,
|
f,
|
||||||
"subpass dependency {} specified an access type that was not supported by the given stages",
|
"subpass dependency {} specified an access type that was not supported by the \
|
||||||
dependency,
|
given stages",
|
||||||
),
|
|
||||||
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,
|
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!(
|
Self::DependencySelfDependencyViewLocalNonzeroOffset { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::DependencySelfDependencyViewMaskMultiple { dependency, subpass } => write!(
|
Self::DependencySelfDependencyViewMaskMultiple {
|
||||||
|
dependency,
|
||||||
|
subpass,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
dependency, subpass,
|
||||||
),
|
),
|
||||||
Self::DependencySourceSubpassAfterDestinationSubpass { dependency } => write!(
|
Self::DependencySourceSubpassAfterDestinationSubpass { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::DependencyStageNotSupported { dependency } => write!(
|
Self::DependencyStageNotSupported { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::DependencyBothSubpassesExternal { dependency } => write!(
|
Self::DependencyBothSubpassesExternal { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::DependencySubpassOutOfRange {
|
Self::DependencySubpassOutOfRange {
|
||||||
@ -1664,25 +1686,35 @@ impl Display for RenderPassCreationError {
|
|||||||
subpass,
|
subpass,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
subpass, dependency,
|
||||||
),
|
),
|
||||||
Self::DependencyViewLocalExternalDependency { dependency } => write!(
|
Self::DependencyViewLocalExternalDependency { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::DependencyViewLocalMultiviewNotEnabled { dependency } => write!(
|
Self::DependencyViewLocalMultiviewNotEnabled { dependency } => write!(
|
||||||
f,
|
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,
|
dependency,
|
||||||
),
|
),
|
||||||
Self::SubpassAttachmentAspectsNotEmpty { subpass, attachment } => write!(
|
Self::SubpassAttachmentAspectsNotEmpty {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassAttachmentLayoutMismatch { subpass, attachment } => write!(
|
Self::SubpassAttachmentLayoutMismatch {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"the layouts of all uses of attachment {} in subpass {} do not match.",
|
"the layouts of all uses of attachment {} in subpass {} do not match.",
|
||||||
attachment, subpass,
|
attachment, subpass,
|
||||||
@ -1693,27 +1725,45 @@ impl Display for RenderPassCreationError {
|
|||||||
usage,
|
usage,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
attachment, usage, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassAttachmentOutOfRange { subpass, attachment } => write!(
|
Self::SubpassAttachmentOutOfRange {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassAttachmentUsageColorDepthStencil { subpass, attachment } => write!(
|
Self::SubpassAttachmentUsageColorDepthStencil {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassAttachmentFormatUsageNotSupported { subpass, attachment, usage, } => write!(
|
Self::SubpassAttachmentFormatUsageNotSupported {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
usage,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, usage, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassColorAttachmentWithResolveNotMultisampled { subpass, attachment } => write!(
|
Self::SubpassColorAttachmentWithResolveNotMultisampled {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassColorDepthStencilAttachmentSamplesMismatch {
|
Self::SubpassColorDepthStencilAttachmentSamplesMismatch {
|
||||||
@ -1723,37 +1773,49 @@ impl Display for RenderPassCreationError {
|
|||||||
first_samples,
|
first_samples,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass, samples, first_samples,
|
||||||
),
|
),
|
||||||
Self::SubpassInputAttachmentAspectsNotCompatible { subpass, attachment } => write!(
|
Self::SubpassInputAttachmentAspectsNotCompatible {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassMaxColorAttachmentsExceeded { .. } => {
|
Self::SubpassMaxColorAttachmentsExceeded { .. } => {
|
||||||
write!(f, "the `max_color_attachments` limit has been exceeded",)
|
write!(f, "the `max_color_attachments` limit has been exceeded")
|
||||||
}
|
}
|
||||||
Self::SubpassMaxMultiviewViewCountExceeded { .. } => {
|
Self::SubpassMaxMultiviewViewCountExceeded { .. } => write!(
|
||||||
write!(f, "the `max_multiview_view_count` limit has been exceeded for a subpass",)
|
f,
|
||||||
},
|
"the `max_multiview_view_count` limit has been exceeded for a subpass",
|
||||||
|
),
|
||||||
Self::SubpassMultiviewMismatch {
|
Self::SubpassMultiviewMismatch {
|
||||||
subpass,
|
subpass,
|
||||||
multiview,
|
multiview,
|
||||||
first_subpass_multiview,
|
first_subpass_multiview,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
subpass, multiview, first_subpass_multiview,
|
||||||
),
|
),
|
||||||
Self::SubpassPreserveAttachmentUsedElsewhere { subpass, attachment } => write!(
|
Self::SubpassPreserveAttachmentUsedElsewhere {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassResolveAttachmentsColorAttachmentsLenMismatch { subpass } => write!(
|
Self::SubpassResolveAttachmentsColorAttachmentsLenMismatch { subpass } => write!(
|
||||||
f,
|
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,
|
subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassResolveAttachmentFormatMismatch {
|
Self::SubpassResolveAttachmentFormatMismatch {
|
||||||
@ -1762,17 +1824,23 @@ impl Display for RenderPassCreationError {
|
|||||||
color_attachment,
|
color_attachment,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
subpass, resolve_attachment, color_attachment,
|
||||||
),
|
),
|
||||||
Self::SubpassResolveAttachmentMultisampled { subpass, attachment } => write!(
|
Self::SubpassResolveAttachmentMultisampled {
|
||||||
|
subpass,
|
||||||
|
attachment,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
attachment, subpass,
|
||||||
),
|
),
|
||||||
Self::SubpassResolveAttachmentWithoutColorAttachment { subpass } => write!(
|
Self::SubpassResolveAttachmentWithoutColorAttachment { subpass } => write!(
|
||||||
f,
|
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,
|
subpass,
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
@ -1780,14 +1848,12 @@ impl Display for RenderPassCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for RenderPassCreationError {
|
impl From<OomError> for RenderPassCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> RenderPassCreationError {
|
fn from(err: OomError) -> RenderPassCreationError {
|
||||||
RenderPassCreationError::OomError(err)
|
RenderPassCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for RenderPassCreationError {
|
impl From<VulkanError> for RenderPassCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> RenderPassCreationError {
|
fn from(err: VulkanError) -> RenderPassCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -1802,7 +1868,6 @@ impl From<VulkanError> for RenderPassCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for RenderPassCreationError {
|
impl From<RequirementNotMet> for RenderPassCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -336,6 +336,7 @@ impl Framebuffer {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `render_pass`.
|
/// - `handle` must be a valid Vulkan object handle created from `render_pass`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
render_pass: Arc<RenderPass>,
|
render_pass: Arc<RenderPass>,
|
||||||
handle: ash::vk::Framebuffer,
|
handle: ash::vk::Framebuffer,
|
||||||
@ -431,7 +432,6 @@ impl PartialEq for Framebuffer {
|
|||||||
impl Eq for Framebuffer {}
|
impl Eq for Framebuffer {}
|
||||||
|
|
||||||
impl Hash for Framebuffer {
|
impl Hash for Framebuffer {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -588,33 +588,28 @@ pub enum FramebufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for FramebufferCreationError {
|
impl From<OomError> for FramebufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for FramebufferCreationError {
|
impl Error for FramebufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FramebufferCreationError {
|
impl Display for FramebufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(
|
Self::OomError(_) => write!(f, "no memory available",),
|
||||||
f,
|
|
||||||
"no memory available",
|
|
||||||
),
|
|
||||||
Self::Attachment2dArrayCompatibleDepthStencil { attachment } => write!(
|
Self::Attachment2dArrayCompatibleDepthStencil { attachment } => write!(
|
||||||
f,
|
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,
|
attachment,
|
||||||
),
|
),
|
||||||
Self::AttachmentComponentMappingNotIdentity { attachment } => write!(
|
Self::AttachmentComponentMappingNotIdentity { attachment } => write!(
|
||||||
@ -632,7 +627,8 @@ impl Display for FramebufferCreationError {
|
|||||||
min,
|
min,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"attachment image {} has an extent ({:?}) smaller than the provided `extent` ({:?})",
|
"attachment image {} has an extent ({:?}) smaller than the provided `extent` \
|
||||||
|
({:?})",
|
||||||
attachment, provided, min,
|
attachment, provided, min,
|
||||||
),
|
),
|
||||||
Self::AttachmentFormatMismatch {
|
Self::AttachmentFormatMismatch {
|
||||||
@ -641,24 +637,19 @@ impl Display for FramebufferCreationError {
|
|||||||
required,
|
required,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
attachment, provided, required,
|
||||||
),
|
),
|
||||||
Self::AttachmentMissingUsage {
|
Self::AttachmentMissingUsage { attachment, usage } => write!(
|
||||||
attachment,
|
|
||||||
usage,
|
|
||||||
} => write!(
|
|
||||||
f,
|
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,
|
attachment, usage,
|
||||||
),
|
),
|
||||||
Self::AttachmentMultipleMipLevels {
|
Self::AttachmentMultipleMipLevels { attachment } => {
|
||||||
attachment,
|
write!(f, "attachment image {} has multiple mip levels", attachment)
|
||||||
} => write!(
|
}
|
||||||
f,
|
|
||||||
"attachment image {} has multiple mip levels",
|
|
||||||
attachment,
|
|
||||||
),
|
|
||||||
Self::AttachmentNotEnoughLayers {
|
Self::AttachmentNotEnoughLayers {
|
||||||
attachment,
|
attachment,
|
||||||
provided,
|
provided,
|
||||||
@ -674,27 +665,29 @@ impl Display for FramebufferCreationError {
|
|||||||
required,
|
required,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
attachment, provided, required,
|
||||||
),
|
),
|
||||||
Self::AttachmentViewType3d {
|
Self::AttachmentViewType3d { attachment } => write!(
|
||||||
attachment,
|
|
||||||
} => write!(
|
|
||||||
f,
|
f,
|
||||||
"attachment image {} has a `ty` of `ImageViewType::Dim3d`",
|
"attachment image {} has a `ty` of `ImageViewType::Dim3d`",
|
||||||
attachment,
|
attachment,
|
||||||
),
|
),
|
||||||
Self::AutoExtentAttachmentsEmpty => write!(
|
Self::AutoExtentAttachmentsEmpty => write!(
|
||||||
f,
|
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!(
|
Self::AutoLayersAttachmentsEmpty => write!(
|
||||||
f,
|
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!(
|
Self::MaxFramebufferExtentExceeded { provided, max } => write!(
|
||||||
f,
|
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,
|
provided, max,
|
||||||
),
|
),
|
||||||
Self::MaxFramebufferLayersExceeded { provided, max } => write!(
|
Self::MaxFramebufferLayersExceeded { provided, max } => write!(
|
||||||
@ -708,7 +701,8 @@ impl Display for FramebufferCreationError {
|
|||||||
min,
|
min,
|
||||||
} => write!(
|
} => write!(
|
||||||
f,
|
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,
|
attachment, provided, min,
|
||||||
),
|
),
|
||||||
Self::MultiviewLayersInvalid => write!(
|
Self::MultiviewLayersInvalid => write!(
|
||||||
@ -720,7 +714,6 @@ impl Display for FramebufferCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for FramebufferCreationError {
|
impl From<VulkanError> for FramebufferCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
Self::from(OomError::from(err))
|
Self::from(OomError::from(err))
|
||||||
}
|
}
|
||||||
|
@ -198,6 +198,7 @@ impl RenderPass {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::RenderPass,
|
handle: ash::vk::RenderPass,
|
||||||
@ -399,21 +400,21 @@ impl RenderPass {
|
|||||||
if !(subpasses1.iter())
|
if !(subpasses1.iter())
|
||||||
.zip(subpasses2.iter())
|
.zip(subpasses2.iter())
|
||||||
.all(|(subpass1, subpass2)| {
|
.all(|(subpass1, subpass2)| {
|
||||||
let &SubpassDescription {
|
let SubpassDescription {
|
||||||
view_mask: view_mask1,
|
view_mask: view_mask1,
|
||||||
input_attachments: ref input_attachments1,
|
input_attachments: input_attachments1,
|
||||||
color_attachments: ref color_attachments1,
|
color_attachments: color_attachments1,
|
||||||
resolve_attachments: ref resolve_attachments1,
|
resolve_attachments: resolve_attachments1,
|
||||||
depth_stencil_attachment: ref depth_stencil_attachment1,
|
depth_stencil_attachment: depth_stencil_attachment1,
|
||||||
preserve_attachments: _,
|
preserve_attachments: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = subpass1;
|
} = subpass1;
|
||||||
let &SubpassDescription {
|
let SubpassDescription {
|
||||||
view_mask: view_mask2,
|
view_mask: view_mask2,
|
||||||
input_attachments: ref input_attachments2,
|
input_attachments: input_attachments2,
|
||||||
color_attachments: ref color_attachments2,
|
color_attachments: color_attachments2,
|
||||||
resolve_attachments: ref resolve_attachments2,
|
resolve_attachments: resolve_attachments2,
|
||||||
depth_stencil_attachment: ref depth_stencil_attachment2,
|
depth_stencil_attachment: depth_stencil_attachment2,
|
||||||
preserve_attachments: _,
|
preserve_attachments: _,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = subpass2;
|
} = subpass2;
|
||||||
@ -546,7 +547,6 @@ impl PartialEq for RenderPass {
|
|||||||
impl Eq for RenderPass {}
|
impl Eq for RenderPass {}
|
||||||
|
|
||||||
impl Hash for RenderPass {
|
impl Hash for RenderPass {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device.hash(state);
|
self.device.hash(state);
|
||||||
@ -727,6 +727,7 @@ impl Subpass {
|
|||||||
|
|
||||||
/// Returns `true` if this subpass is compatible with the fragment output definition.
|
/// Returns `true` if this subpass is compatible with the fragment output definition.
|
||||||
// TODO: return proper error
|
// TODO: return proper error
|
||||||
|
#[inline]
|
||||||
pub fn is_compatible_with(&self, shader_interface: &ShaderInterface) -> bool {
|
pub fn is_compatible_with(&self, shader_interface: &ShaderInterface) -> bool {
|
||||||
self.render_pass
|
self.render_pass
|
||||||
.is_compatible_with_shader(self.subpass_id, shader_interface)
|
.is_compatible_with_shader(self.subpass_id, shader_interface)
|
||||||
|
@ -448,6 +448,7 @@ impl Sampler {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::Sampler,
|
handle: ash::vk::Sampler,
|
||||||
@ -752,7 +753,6 @@ impl PartialEq for Sampler {
|
|||||||
impl Eq for Sampler {}
|
impl Eq for Sampler {}
|
||||||
|
|
||||||
impl Hash for Sampler {
|
impl Hash for Sampler {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -854,22 +854,19 @@ pub enum SamplerCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for SamplerCreationError {
|
impl Error for SamplerCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
SamplerCreationError::OomError(ref err) => Some(err),
|
SamplerCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SamplerCreationError {
|
impl Display for SamplerCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
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 {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -878,61 +875,77 @@ impl Display for SamplerCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
Self::AnisotropyInvalidFilter { .. } => {
|
||||||
Self::AnisotropyInvalidFilter { .. } => write!(f, "anisotropy was enabled with an invalid filter"),
|
write!(f, "anisotropy was enabled with an invalid filter")
|
||||||
Self::CompareInvalidReductionMode { .. } => write!(f, "depth comparison was enabled with an invalid reduction mode"),
|
}
|
||||||
|
Self::CompareInvalidReductionMode { .. } => write!(
|
||||||
|
f,
|
||||||
|
"depth comparison was enabled with an invalid reduction mode",
|
||||||
|
),
|
||||||
Self::MaxSamplerAnisotropyExceeded { .. } => {
|
Self::MaxSamplerAnisotropyExceeded { .. } => {
|
||||||
write!(f, "max_sampler_anisotropy limit exceeded")
|
write!(f, "max_sampler_anisotropy limit exceeded")
|
||||||
}
|
}
|
||||||
Self::MaxSamplerLodBiasExceeded { .. } => write!(f, "mip lod bias limit exceeded"),
|
Self::MaxSamplerLodBiasExceeded { .. } => write!(f, "mip lod bias limit exceeded"),
|
||||||
Self::SamplerYcbcrConversionAnisotropyEnabled => write!(
|
Self::SamplerYcbcrConversionAnisotropyEnabled => write!(
|
||||||
f,
|
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!(
|
Self::SamplerYcbcrConversionUnnormalizedCoordinatesEnabled => write!(
|
||||||
f,
|
f,
|
||||||
"sampler YCbCr conversion was enabled together with unnormalized coordinates"
|
"sampler YCbCr conversion was enabled together with unnormalized coordinates",
|
||||||
),
|
),
|
||||||
Self::UnnormalizedCoordinatesAnisotropyEnabled => write!(
|
Self::UnnormalizedCoordinatesAnisotropyEnabled => write!(
|
||||||
f,
|
f,
|
||||||
"unnormalized coordinates were enabled together with anisotropy"
|
"unnormalized coordinates were enabled together with anisotropy",
|
||||||
),
|
),
|
||||||
Self::UnnormalizedCoordinatesCompareEnabled => write!(
|
Self::UnnormalizedCoordinatesCompareEnabled => write!(
|
||||||
f,
|
f,
|
||||||
"unnormalized coordinates were enabled together with depth comparison"
|
"unnormalized coordinates were enabled together with depth comparison",
|
||||||
),
|
),
|
||||||
Self::UnnormalizedCoordinatesFiltersNotEqual { .. } => write!(
|
Self::UnnormalizedCoordinatesFiltersNotEqual { .. } => write!(
|
||||||
f,
|
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!(
|
Self::UnnormalizedCoordinatesInvalidAddressMode { .. } => write!(
|
||||||
f,
|
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!(
|
Self::UnnormalizedCoordinatesInvalidMipmapMode { .. } => write!(
|
||||||
f,
|
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!(
|
Self::UnnormalizedCoordinatesNonzeroLod { .. } => write!(
|
||||||
f,
|
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 {
|
impl From<OomError> for SamplerCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for SamplerCreationError {
|
impl From<VulkanError> for SamplerCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
@ -944,7 +957,6 @@ impl From<VulkanError> for SamplerCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for SamplerCreationError {
|
impl From<RequirementNotMet> for SamplerCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -1084,6 +1096,7 @@ pub struct SamplerCreateInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for SamplerCreateInfo {
|
impl Default for SamplerCreateInfo {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
mag_filter: Filter::Nearest,
|
mag_filter: Filter::Nearest,
|
||||||
@ -1475,16 +1488,55 @@ impl Error for SamplerImageViewIncompatibleError {}
|
|||||||
impl Display for SamplerImageViewIncompatibleError {
|
impl Display for SamplerImageViewIncompatibleError {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::BorderColorFormatNotCompatible => write!(f, "the sampler has a border color with a numeric type different from the image view"),
|
Self::BorderColorFormatNotCompatible => write!(
|
||||||
Self::BorderColorOpaqueBlackNotIdentitySwizzled => write!(f, "the sampler has an opaque black border color, but the image view is not identity swizzled"),
|
f,
|
||||||
Self::DepthComparisonNotSupported => write!(f, "the sampler has depth comparison enabled, but this is not supported by the image view"),
|
"the sampler has a border color with a numeric type different from 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::BorderColorOpaqueBlackNotIdentitySwizzled => write!(
|
||||||
Self::FilterCubicNotSupported => write!(f, "the sampler uses a cubic filter, but this is not supported by the image view's format features"),
|
f,
|
||||||
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"),
|
"the sampler has an opaque black border color, but the image view is not identity \
|
||||||
Self::MipmapModeLinearNotSupported => write!(f, "the sampler uses a linear mipmap mode, but this is not supported by the image view's format features"),
|
swizzled",
|
||||||
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::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`",
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -362,6 +362,7 @@ impl SamplerYcbcrConversion {
|
|||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
/// - `create_info.format` must be `Some`.
|
/// - `create_info.format` must be `Some`.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::SamplerYcbcrConversion,
|
handle: ash::vk::SamplerYcbcrConversion,
|
||||||
@ -377,6 +378,7 @@ impl SamplerYcbcrConversion {
|
|||||||
force_explicit_reconstruction,
|
force_explicit_reconstruction,
|
||||||
_ne: _,
|
_ne: _,
|
||||||
} = create_info;
|
} = create_info;
|
||||||
|
|
||||||
Arc::new(SamplerYcbcrConversion {
|
Arc::new(SamplerYcbcrConversion {
|
||||||
handle,
|
handle,
|
||||||
device,
|
device,
|
||||||
@ -506,7 +508,6 @@ impl PartialEq for SamplerYcbcrConversion {
|
|||||||
impl Eq for SamplerYcbcrConversion {}
|
impl Eq for SamplerYcbcrConversion {}
|
||||||
|
|
||||||
impl Hash for SamplerYcbcrConversion {
|
impl Hash for SamplerYcbcrConversion {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -557,21 +558,18 @@ pub enum SamplerYcbcrConversionCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for SamplerYcbcrConversionCreationError {
|
impl Error for SamplerYcbcrConversionCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
SamplerYcbcrConversionCreationError::OomError(ref err) => Some(err),
|
SamplerYcbcrConversionCreationError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SamplerYcbcrConversionCreationError {
|
impl Display for SamplerYcbcrConversionCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -580,7 +578,6 @@ impl Display for SamplerYcbcrConversionCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::CubicFilterNotSupported => {
|
Self::CubicFilterNotSupported => {
|
||||||
write!(f, "the `Cubic` filter was specified")
|
write!(f, "the `Cubic` filter was specified")
|
||||||
}
|
}
|
||||||
@ -596,43 +593,37 @@ impl Display for SamplerYcbcrConversionCreationError {
|
|||||||
Self::FormatChromaOffsetNotSupported => {
|
Self::FormatChromaOffsetNotSupported => {
|
||||||
write!(f, "the format does not support the chosen chroma offsets")
|
write!(f, "the format does not support the chosen chroma offsets")
|
||||||
}
|
}
|
||||||
Self::FormatInvalidComponentMapping => {
|
Self::FormatInvalidComponentMapping => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"the component mapping was not valid for use with the chosen format",
|
||||||
"the component mapping was not valid for use with the chosen format"
|
),
|
||||||
)
|
Self::FormatForceExplicitReconstructionNotSupported => write!(
|
||||||
}
|
f,
|
||||||
Self::FormatForceExplicitReconstructionNotSupported => {
|
"the format does not support `force_explicit_reconstruction`",
|
||||||
write!(
|
),
|
||||||
f,
|
|
||||||
"the format does not support `force_explicit_reconstruction`"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Self::FormatLinearFilterNotSupported => {
|
Self::FormatLinearFilterNotSupported => {
|
||||||
write!(f, "the format does not support the `Linear` filter")
|
write!(f, "the format does not support the `Linear` filter")
|
||||||
}
|
}
|
||||||
Self::YcbcrModelInvalidComponentMapping => {
|
Self::YcbcrModelInvalidComponentMapping => write!(
|
||||||
write!(
|
f,
|
||||||
f,
|
"the component mapping was not valid for use with the chosen YCbCr model",
|
||||||
"the component mapping was not valid for use with the chosen YCbCr model"
|
),
|
||||||
)
|
Self::YcbcrRangeFormatNotEnoughBits => write!(
|
||||||
}
|
f,
|
||||||
Self::YcbcrRangeFormatNotEnoughBits => {
|
"for the chosen `ycbcr_range`, the R, G or B components being read from the \
|
||||||
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")
|
`format` do not have the minimum number of required bits",
|
||||||
}
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for SamplerYcbcrConversionCreationError {
|
impl From<OomError> for SamplerYcbcrConversionCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> SamplerYcbcrConversionCreationError {
|
fn from(err: OomError) -> SamplerYcbcrConversionCreationError {
|
||||||
SamplerYcbcrConversionCreationError::OomError(err)
|
SamplerYcbcrConversionCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for SamplerYcbcrConversionCreationError {
|
impl From<VulkanError> for SamplerYcbcrConversionCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> SamplerYcbcrConversionCreationError {
|
fn from(err: VulkanError) -> SamplerYcbcrConversionCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -647,7 +638,6 @@ impl From<VulkanError> for SamplerYcbcrConversionCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for SamplerYcbcrConversionCreationError {
|
impl From<RequirementNotMet> for SamplerYcbcrConversionCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -63,6 +63,7 @@ impl ShaderModule {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - The SPIR-V code is not validated beyond the minimum needed to extract the information.
|
/// - The SPIR-V code is not validated beyond the minimum needed to extract the information.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_words(
|
pub unsafe fn from_words(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
words: &[u32],
|
words: &[u32],
|
||||||
@ -84,11 +85,13 @@ impl ShaderModule {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the length of `bytes` is not a multiple of 4.
|
/// - Panics if the length of `bytes` is not a multiple of 4.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_bytes(
|
pub unsafe fn from_bytes(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
bytes: &[u8],
|
bytes: &[u8],
|
||||||
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
|
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
|
||||||
assert!((bytes.len() % 4) == 0);
|
assert!((bytes.len() % 4) == 0);
|
||||||
|
|
||||||
Self::from_words(
|
Self::from_words(
|
||||||
device,
|
device,
|
||||||
std::slice::from_raw_parts(
|
std::slice::from_raw_parts(
|
||||||
@ -204,6 +207,7 @@ impl ShaderModule {
|
|||||||
entry_points: impl IntoIterator<Item = (String, ExecutionModel, EntryPointInfo)>,
|
entry_points: impl IntoIterator<Item = (String, ExecutionModel, EntryPointInfo)>,
|
||||||
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
|
) -> Result<Arc<ShaderModule>, ShaderCreationError> {
|
||||||
assert!((bytes.len() % 4) == 0);
|
assert!((bytes.len() % 4) == 0);
|
||||||
|
|
||||||
Self::from_words_with_data(
|
Self::from_words_with_data(
|
||||||
device,
|
device,
|
||||||
std::slice::from_raw_parts(
|
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
|
/// 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
|
/// point with that name exists in the shader module or if multiple entry points with the same
|
||||||
/// name exist.
|
/// name exist.
|
||||||
|
#[inline]
|
||||||
pub fn entry_point<'a>(&'a self, name: &str) -> Option<EntryPoint<'a>> {
|
pub fn entry_point<'a>(&'a self, name: &str) -> Option<EntryPoint<'a>> {
|
||||||
self.entry_points.get(name).and_then(|infos| {
|
self.entry_points.get(name).and_then(|infos| {
|
||||||
if infos.len() == 1 {
|
if infos.len() == 1 {
|
||||||
@ -234,8 +239,9 @@ impl ShaderModule {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns information about the entry point with the provided name and execution model. Returns
|
/// Returns information about the entry point with the provided name and execution model.
|
||||||
/// `None` if no entry and execution model exists in the shader module.
|
/// Returns `None` if no entry and execution model exists in the shader module.
|
||||||
|
#[inline]
|
||||||
pub fn entry_point_with_execution<'a>(
|
pub fn entry_point_with_execution<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
name: &str,
|
name: &str,
|
||||||
@ -294,7 +300,6 @@ pub enum ShaderCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for ShaderCreationError {
|
impl Error for ShaderCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
@ -604,6 +609,7 @@ pub struct DescriptorIdentifier {
|
|||||||
impl DescriptorRequirements {
|
impl DescriptorRequirements {
|
||||||
/// Produces the intersection of two descriptor requirements, so that the requirements of both
|
/// Produces the intersection of two descriptor requirements, so that the requirements of both
|
||||||
/// are satisfied. An error is returned if the requirements conflict.
|
/// are satisfied. An error is returned if the requirements conflict.
|
||||||
|
#[inline]
|
||||||
pub fn intersection(&self, other: &Self) -> Result<Self, DescriptorRequirementsIncompatible> {
|
pub fn intersection(&self, other: &Self) -> Result<Self, DescriptorRequirementsIncompatible> {
|
||||||
let descriptor_types: Vec<_> = self
|
let descriptor_types: Vec<_> = self
|
||||||
.descriptor_types
|
.descriptor_types
|
||||||
@ -731,7 +737,7 @@ pub struct SpecializationConstantRequirements {
|
|||||||
///
|
///
|
||||||
/// This trait is implemented on `()` for shaders that don't have any specialization constant.
|
/// This trait is implemented on `()` for shaders that don't have any specialization constant.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// use vulkano::shader::SpecializationConstants;
|
/// use vulkano::shader::SpecializationConstants;
|
||||||
@ -774,7 +780,6 @@ pub struct SpecializationConstantRequirements {
|
|||||||
/// - The `SpecializationMapEntry` returned must contain valid offsets and sizes.
|
/// - The `SpecializationMapEntry` returned must contain valid offsets and sizes.
|
||||||
/// - The size of each `SpecializationMapEntry` must match the size of the corresponding constant
|
/// - The size of each `SpecializationMapEntry` must match the size of the corresponding constant
|
||||||
/// (`4` for booleans).
|
/// (`4` for booleans).
|
||||||
///
|
|
||||||
pub unsafe trait SpecializationConstants {
|
pub unsafe trait SpecializationConstants {
|
||||||
/// Returns descriptors of the struct's layout.
|
/// Returns descriptors of the struct's layout.
|
||||||
fn descriptors() -> &'static [SpecializationMapEntry];
|
fn descriptors() -> &'static [SpecializationMapEntry];
|
||||||
@ -840,6 +845,7 @@ impl ShaderInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a description of an empty shader interface.
|
/// Creates a description of an empty shader interface.
|
||||||
|
#[inline]
|
||||||
pub const fn empty() -> ShaderInterface {
|
pub const fn empty() -> ShaderInterface {
|
||||||
ShaderInterface {
|
ShaderInterface {
|
||||||
elements: Vec::new(),
|
elements: Vec::new(),
|
||||||
@ -855,6 +861,7 @@ impl ShaderInterface {
|
|||||||
/// Checks whether the interface is potentially compatible with another one.
|
/// Checks whether the interface is potentially compatible with another one.
|
||||||
///
|
///
|
||||||
/// Returns `Ok` if the two interfaces are compatible.
|
/// Returns `Ok` if the two interfaces are compatible.
|
||||||
|
#[inline]
|
||||||
pub fn matches(&self, other: &ShaderInterface) -> Result<(), ShaderInterfaceMismatchError> {
|
pub fn matches(&self, other: &ShaderInterface) -> Result<(), ShaderInterfaceMismatchError> {
|
||||||
if self.elements().len() != other.elements().len() {
|
if self.elements().len() != other.elements().len() {
|
||||||
return Err(ShaderInterfaceMismatchError::ElementsCountMismatch {
|
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
|
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/chap43.html#formats-numericformat
|
||||||
impl From<NumericType> for ShaderScalarType {
|
impl From<NumericType> for ShaderScalarType {
|
||||||
|
#[inline]
|
||||||
fn from(val: NumericType) -> Self {
|
fn from(val: NumericType) -> Self {
|
||||||
match val {
|
match val {
|
||||||
NumericType::SFLOAT => Self::Float,
|
NumericType::SFLOAT => Self::Float,
|
||||||
@ -1023,12 +1031,11 @@ pub enum ShaderInterfaceMismatchError {
|
|||||||
impl Error for ShaderInterfaceMismatchError {}
|
impl Error for ShaderInterfaceMismatchError {}
|
||||||
|
|
||||||
impl Display for ShaderInterfaceMismatchError {
|
impl Display for ShaderInterfaceMismatchError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
ShaderInterfaceMismatchError::ElementsCountMismatch { .. } => {
|
ShaderInterfaceMismatchError::ElementsCountMismatch { .. } => {
|
||||||
"the number of elements mismatches"
|
"the number of elements mismatches"
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ use ahash::{HashMap, HashSet};
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
/// Returns an iterator of the capabilities used by `spirv`.
|
/// Returns an iterator of the capabilities used by `spirv`.
|
||||||
|
#[inline]
|
||||||
pub fn spirv_capabilities(spirv: &Spirv) -> impl Iterator<Item = &Capability> {
|
pub fn spirv_capabilities(spirv: &Spirv) -> impl Iterator<Item = &Capability> {
|
||||||
spirv
|
spirv
|
||||||
.iter_capability()
|
.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`.
|
/// Returns an iterator of the extensions used by `spirv`.
|
||||||
|
#[inline]
|
||||||
pub fn spirv_extensions(spirv: &Spirv) -> impl Iterator<Item = &str> {
|
pub fn spirv_extensions(spirv: &Spirv) -> impl Iterator<Item = &str> {
|
||||||
spirv
|
spirv
|
||||||
.iter_extension()
|
.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.
|
/// Returns an iterator over all entry points in `spirv`, with information about the entry point.
|
||||||
|
#[inline]
|
||||||
pub fn entry_points(
|
pub fn entry_points(
|
||||||
spirv: &Spirv,
|
spirv: &Spirv,
|
||||||
) -> impl Iterator<Item = (String, ExecutionModel, EntryPointInfo)> + '_ {
|
) -> impl Iterator<Item = (String, ExecutionModel, EntryPointInfo)> + '_ {
|
||||||
@ -56,13 +59,13 @@ pub fn entry_points(
|
|||||||
|
|
||||||
spirv.iter_entry_point().filter_map(move |instruction| {
|
spirv.iter_entry_point().filter_map(move |instruction| {
|
||||||
let (execution_model, function_id, entry_point_name, interface) = match instruction {
|
let (execution_model, function_id, entry_point_name, interface) = match instruction {
|
||||||
&Instruction::EntryPoint {
|
Instruction::EntryPoint {
|
||||||
ref execution_model,
|
execution_model,
|
||||||
entry_point,
|
entry_point,
|
||||||
ref name,
|
name,
|
||||||
ref interface,
|
interface,
|
||||||
..
|
..
|
||||||
} => (execution_model, entry_point, name, interface),
|
} => (execution_model, *entry_point, name, interface),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -210,7 +213,6 @@ fn inspect_entry_point(
|
|||||||
spirv: &Spirv,
|
spirv: &Spirv,
|
||||||
entry_point: Id,
|
entry_point: Id,
|
||||||
) -> HashMap<(u32, u32), DescriptorRequirements> {
|
) -> HashMap<(u32, u32), DescriptorRequirements> {
|
||||||
#[inline]
|
|
||||||
fn instruction_chain<'a, const N: usize>(
|
fn instruction_chain<'a, const N: usize>(
|
||||||
result: &'a mut HashMap<Id, DescriptorVariable>,
|
result: &'a mut HashMap<Id, DescriptorVariable>,
|
||||||
global: &HashMap<Id, DescriptorVariable>,
|
global: &HashMap<Id, DescriptorVariable>,
|
||||||
@ -226,8 +228,8 @@ fn inspect_entry_point(
|
|||||||
return Some((variable, Some(0)));
|
return Some((variable, Some(0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let (id, indexes) = match spirv.id(id).instruction() {
|
let (id, indexes) = match *spirv.id(id).instruction() {
|
||||||
&Instruction::AccessChain {
|
Instruction::AccessChain {
|
||||||
base, ref indexes, ..
|
base, ref indexes, ..
|
||||||
} => (base, indexes),
|
} => (base, indexes),
|
||||||
_ => return None,
|
_ => return None,
|
||||||
@ -237,8 +239,8 @@ fn inspect_entry_point(
|
|||||||
// Variable was accessed with an access chain.
|
// Variable was accessed with an access chain.
|
||||||
// Retrieve index from instruction if it's a constant value.
|
// Retrieve index from instruction if it's a constant value.
|
||||||
// TODO: handle a `None` index too?
|
// TODO: handle a `None` index too?
|
||||||
let index = match spirv.id(*indexes.first().unwrap()).instruction() {
|
let index = match *spirv.id(*indexes.first().unwrap()).instruction() {
|
||||||
&Instruction::Constant { ref value, .. } => Some(value[0]),
|
Instruction::Constant { ref value, .. } => Some(value[0]),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
let variable = result.entry(id).or_insert_with(|| variable.clone());
|
let variable = result.entry(id).or_insert_with(|| variable.clone());
|
||||||
@ -248,26 +250,23 @@ fn inspect_entry_point(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inst_image_texel_pointer(spirv: &Spirv, id: Id) -> Option<Id> {
|
fn inst_image_texel_pointer(spirv: &Spirv, id: Id) -> Option<Id> {
|
||||||
match spirv.id(id).instruction() {
|
match *spirv.id(id).instruction() {
|
||||||
&Instruction::ImageTexelPointer { image, .. } => Some(image),
|
Instruction::ImageTexelPointer { image, .. } => Some(image),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inst_load(spirv: &Spirv, id: Id) -> Option<Id> {
|
fn inst_load(spirv: &Spirv, id: Id) -> Option<Id> {
|
||||||
match spirv.id(id).instruction() {
|
match *spirv.id(id).instruction() {
|
||||||
&Instruction::Load { pointer, .. } => Some(pointer),
|
Instruction::Load { pointer, .. } => Some(pointer),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn inst_sampled_image(spirv: &Spirv, id: Id) -> Option<Id> {
|
fn inst_sampled_image(spirv: &Spirv, id: Id) -> Option<Id> {
|
||||||
match spirv.id(id).instruction() {
|
match *spirv.id(id).instruction() {
|
||||||
&Instruction::SampledImage { sampler, .. } => Some(sampler),
|
Instruction::SampledImage { sampler, .. } => Some(sampler),
|
||||||
_ => Some(id),
|
_ => Some(id),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -283,15 +282,15 @@ fn inspect_entry_point(
|
|||||||
let mut in_function = false;
|
let mut in_function = false;
|
||||||
for instruction in spirv.instructions() {
|
for instruction in spirv.instructions() {
|
||||||
if !in_function {
|
if !in_function {
|
||||||
match instruction {
|
match *instruction {
|
||||||
Instruction::Function { result_id, .. } if result_id == &function => {
|
Instruction::Function { result_id, .. } if result_id == function => {
|
||||||
in_function = true;
|
in_function = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match instruction {
|
match *instruction {
|
||||||
&Instruction::AtomicLoad { pointer, .. } => {
|
Instruction::AtomicLoad { pointer, .. } => {
|
||||||
// Storage buffer
|
// Storage buffer
|
||||||
instruction_chain(result, global, spirv, [], pointer);
|
instruction_chain(result, global, spirv, [], pointer);
|
||||||
|
|
||||||
@ -307,26 +306,26 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::AtomicStore { pointer, .. }
|
Instruction::AtomicStore { pointer, .. }
|
||||||
| &Instruction::AtomicExchange { pointer, .. }
|
| Instruction::AtomicExchange { pointer, .. }
|
||||||
| &Instruction::AtomicCompareExchange { pointer, .. }
|
| Instruction::AtomicCompareExchange { pointer, .. }
|
||||||
| &Instruction::AtomicCompareExchangeWeak { pointer, .. }
|
| Instruction::AtomicCompareExchangeWeak { pointer, .. }
|
||||||
| &Instruction::AtomicIIncrement { pointer, .. }
|
| Instruction::AtomicIIncrement { pointer, .. }
|
||||||
| &Instruction::AtomicIDecrement { pointer, .. }
|
| Instruction::AtomicIDecrement { pointer, .. }
|
||||||
| &Instruction::AtomicIAdd { pointer, .. }
|
| Instruction::AtomicIAdd { pointer, .. }
|
||||||
| &Instruction::AtomicISub { pointer, .. }
|
| Instruction::AtomicISub { pointer, .. }
|
||||||
| &Instruction::AtomicSMin { pointer, .. }
|
| Instruction::AtomicSMin { pointer, .. }
|
||||||
| &Instruction::AtomicUMin { pointer, .. }
|
| Instruction::AtomicUMin { pointer, .. }
|
||||||
| &Instruction::AtomicSMax { pointer, .. }
|
| Instruction::AtomicSMax { pointer, .. }
|
||||||
| &Instruction::AtomicUMax { pointer, .. }
|
| Instruction::AtomicUMax { pointer, .. }
|
||||||
| &Instruction::AtomicAnd { pointer, .. }
|
| Instruction::AtomicAnd { pointer, .. }
|
||||||
| &Instruction::AtomicOr { pointer, .. }
|
| Instruction::AtomicOr { pointer, .. }
|
||||||
| &Instruction::AtomicXor { pointer, .. }
|
| Instruction::AtomicXor { pointer, .. }
|
||||||
| &Instruction::AtomicFlagTestAndSet { pointer, .. }
|
| Instruction::AtomicFlagTestAndSet { pointer, .. }
|
||||||
| &Instruction::AtomicFlagClear { pointer, .. }
|
| Instruction::AtomicFlagClear { pointer, .. }
|
||||||
| &Instruction::AtomicFMinEXT { pointer, .. }
|
| Instruction::AtomicFMinEXT { pointer, .. }
|
||||||
| &Instruction::AtomicFMaxEXT { pointer, .. }
|
| Instruction::AtomicFMaxEXT { pointer, .. }
|
||||||
| &Instruction::AtomicFAddEXT { pointer, .. } => {
|
| Instruction::AtomicFAddEXT { pointer, .. } => {
|
||||||
// Storage buffer
|
// Storage buffer
|
||||||
if let Some((variable, Some(index))) =
|
if let Some((variable, Some(index))) =
|
||||||
instruction_chain(result, global, spirv, [], pointer)
|
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, [], target);
|
||||||
instruction_chain(result, global, spirv, [], source);
|
instruction_chain(result, global, spirv, [], source);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::CopyObject { operand, .. } => {
|
Instruction::CopyObject { operand, .. } => {
|
||||||
instruction_chain(result, global, spirv, [], operand);
|
instruction_chain(result, global, spirv, [], operand);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ExtInst { ref operands, .. } => {
|
Instruction::ExtInst { ref operands, .. } => {
|
||||||
// We don't know which extended instructions take pointers,
|
// We don't know which extended instructions take pointers,
|
||||||
// so we must interpret every operand as a pointer.
|
// so we must interpret every operand as a pointer.
|
||||||
for &operand in operands {
|
for &operand in operands {
|
||||||
@ -364,7 +363,7 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::FunctionCall {
|
Instruction::FunctionCall {
|
||||||
function,
|
function,
|
||||||
ref arguments,
|
ref arguments,
|
||||||
..
|
..
|
||||||
@ -386,16 +385,16 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::FunctionEnd => return,
|
Instruction::FunctionEnd => return,
|
||||||
|
|
||||||
&Instruction::ImageGather {
|
Instruction::ImageGather {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseGather {
|
| Instruction::ImageSparseGather {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
@ -420,8 +419,8 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageDrefGather { sampled_image, .. }
|
Instruction::ImageDrefGather { sampled_image, .. }
|
||||||
| &Instruction::ImageSparseDrefGather { sampled_image, .. } => {
|
| Instruction::ImageSparseDrefGather { sampled_image, .. } => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
result,
|
result,
|
||||||
global,
|
global,
|
||||||
@ -437,24 +436,24 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageSampleImplicitLod {
|
Instruction::ImageSampleImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSampleProjImplicitLod {
|
| Instruction::ImageSampleProjImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleProjImplicitLod {
|
| Instruction::ImageSparseSampleProjImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleImplicitLod {
|
| Instruction::ImageSparseSampleImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
@ -478,14 +477,14 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageSampleProjExplicitLod {
|
Instruction::ImageSampleProjExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleProjExplicitLod {
|
| Instruction::ImageSparseSampleProjExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
@ -508,24 +507,24 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageSampleDrefImplicitLod {
|
Instruction::ImageSampleDrefImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSampleProjDrefImplicitLod {
|
| Instruction::ImageSampleProjDrefImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleDrefImplicitLod {
|
| Instruction::ImageSparseSampleDrefImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleProjDrefImplicitLod {
|
| Instruction::ImageSparseSampleProjDrefImplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
@ -550,24 +549,24 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageSampleDrefExplicitLod {
|
Instruction::ImageSampleDrefExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSampleProjDrefExplicitLod {
|
| Instruction::ImageSampleProjDrefExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleDrefExplicitLod {
|
| Instruction::ImageSparseSampleDrefExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleProjDrefExplicitLod {
|
| Instruction::ImageSparseSampleProjDrefExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
if let Some((variable, Some(index))) = instruction_chain(
|
||||||
@ -591,14 +590,14 @@ fn inspect_entry_point(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageSampleExplicitLod {
|
Instruction::ImageSampleExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::ImageSparseSampleExplicitLod {
|
| Instruction::ImageSparseSampleExplicitLod {
|
||||||
sampled_image,
|
sampled_image,
|
||||||
ref image_operands,
|
image_operands,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Some((variable, Some(index))) = instruction_chain(
|
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_chain(result, global, spirv, [], image);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::ImageRead { image, .. } => {
|
Instruction::ImageRead { image, .. } => {
|
||||||
if let Some((variable, Some(index))) =
|
if let Some((variable, Some(index))) =
|
||||||
instruction_chain(result, global, spirv, [inst_load], image)
|
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))) =
|
if let Some((variable, Some(index))) =
|
||||||
instruction_chain(result, global, spirv, [inst_load], image)
|
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_chain(result, global, spirv, [], pointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::SampledImage { image, sampler, .. } => {
|
Instruction::SampledImage { image, sampler, .. } => {
|
||||||
let identifier =
|
let identifier =
|
||||||
match instruction_chain(result, global, spirv, [inst_load], image) {
|
match instruction_chain(result, global, spirv, [inst_load], image) {
|
||||||
Some((variable, Some(index))) => DescriptorIdentifier {
|
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))) =
|
if let Some((variable, Some(index))) =
|
||||||
instruction_chain(result, global, spirv, [], pointer)
|
instruction_chain(result, global, spirv, [], pointer)
|
||||||
{
|
{
|
||||||
@ -696,6 +695,7 @@ fn inspect_entry_point(
|
|||||||
spirv,
|
spirv,
|
||||||
entry_point,
|
entry_point,
|
||||||
);
|
);
|
||||||
|
|
||||||
result
|
result
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_, variable)| ((variable.set, variable.binding), variable.reqs))
|
.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 (mut next_type_id, is_storage_buffer) = {
|
||||||
let variable_type_id = match variable_id_info.instruction() {
|
let variable_type_id = match *variable_id_info.instruction() {
|
||||||
Instruction::Variable { result_type_id, .. } => *result_type_id,
|
Instruction::Variable { result_type_id, .. } => result_type_id,
|
||||||
_ => panic!("Id {} is not a variable", variable_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 {
|
Instruction::TypePointer {
|
||||||
ty, storage_class, ..
|
ty, storage_class, ..
|
||||||
} => (Some(*ty), *storage_class == StorageClass::StorageBuffer),
|
} => (Some(ty), storage_class == StorageClass::StorageBuffer),
|
||||||
_ => panic!(
|
_ => panic!(
|
||||||
"Variable {} result_type_id does not refer to a TypePointer instruction",
|
"Variable {} result_type_id does not refer to a TypePointer instruction",
|
||||||
variable_id
|
variable_id
|
||||||
@ -733,7 +733,7 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
|||||||
while let Some(id) = next_type_id {
|
while let Some(id) = next_type_id {
|
||||||
let id_info = spirv.id(id);
|
let id_info = spirv.id(id);
|
||||||
|
|
||||||
next_type_id = match id_info.instruction() {
|
next_type_id = match *id_info.instruction() {
|
||||||
Instruction::TypeStruct { .. } => {
|
Instruction::TypeStruct { .. } => {
|
||||||
let decoration_block = id_info.iter_decoration().any(|instruction| {
|
let decoration_block = id_info.iter_decoration().any(|instruction| {
|
||||||
matches!(
|
matches!(
|
||||||
@ -757,7 +757,8 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
|||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
decoration_block ^ decoration_buffer_block,
|
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 {
|
if decoration_buffer_block || decoration_block && is_storage_buffer {
|
||||||
@ -775,16 +776,20 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeImage {
|
Instruction::TypeImage {
|
||||||
sampled_type,
|
sampled_type,
|
||||||
ref dim,
|
dim,
|
||||||
arrayed,
|
arrayed,
|
||||||
ms,
|
ms,
|
||||||
sampled,
|
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_format = image_format.clone().into();
|
||||||
reqs.image_multisampled = ms != 0;
|
reqs.image_multisampled = ms != 0;
|
||||||
reqs.image_scalar_type = Some(match *spirv.id(sampled_type).instruction() {
|
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 => {
|
Dim::SubpassData => {
|
||||||
assert!(
|
assert!(
|
||||||
reqs.image_format.is_none(),
|
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!(sampled == 2, "If Dim is SubpassData, Sampled must be 2");
|
||||||
assert!(arrayed == 0, "If Dim is SubpassData, Arrayed must be 0");
|
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
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeSampler { .. } => {
|
Instruction::TypeSampler { .. } => {
|
||||||
reqs.descriptor_types = vec![DescriptorType::Sampler];
|
reqs.descriptor_types = vec![DescriptorType::Sampler];
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeSampledImage { image_type, .. } => {
|
Instruction::TypeSampledImage { image_type, .. } => {
|
||||||
reqs.descriptor_types = vec![DescriptorType::CombinedImageSampler];
|
reqs.descriptor_types = vec![DescriptorType::CombinedImageSampler];
|
||||||
|
|
||||||
Some(image_type)
|
Some(image_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeArray {
|
Instruction::TypeArray {
|
||||||
element_type,
|
element_type,
|
||||||
length,
|
length,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
let len = match spirv.id(length).instruction() {
|
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)
|
value.iter().rev().fold(0, |a, &b| (a << 32) | b as u64)
|
||||||
}
|
}
|
||||||
_ => panic!("failed to find array length"),
|
_ => panic!("failed to find array length"),
|
||||||
@ -883,23 +890,28 @@ fn descriptor_requirements_of(spirv: &Spirv, variable_id: Id) -> DescriptorVaria
|
|||||||
Some(element_type)
|
Some(element_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeRuntimeArray { element_type, .. } => {
|
Instruction::TypeRuntimeArray { element_type, .. } => {
|
||||||
reqs.descriptor_count = None;
|
reqs.descriptor_count = None;
|
||||||
|
|
||||||
Some(element_type)
|
Some(element_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
&Instruction::TypeAccelerationStructureKHR { .. } => None, // FIXME temporary workaround
|
Instruction::TypeAccelerationStructureKHR { .. } => None, // FIXME temporary workaround
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
let name = variable_id_info
|
let name = variable_id_info
|
||||||
.iter_name()
|
.iter_name()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Name { name, .. } => Some(name.as_str()),
|
Instruction::Name { ref name, .. } => Some(name.as_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap_or("__unnamed");
|
.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 {
|
DescriptorVariable {
|
||||||
set: variable_id_info
|
set: variable_id_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration: Decoration::DescriptorSet { descriptor_set },
|
decoration: Decoration::DescriptorSet { descriptor_set },
|
||||||
..
|
..
|
||||||
} => Some(*descriptor_set),
|
} => Some(descriptor_set),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
binding: variable_id_info
|
binding: variable_id_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration: Decoration::Binding { binding_point },
|
decoration: Decoration::Binding { binding_point },
|
||||||
..
|
..
|
||||||
} => Some(*binding_point),
|
} => Some(binding_point),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap(),
|
.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> {
|
fn push_constant_requirements(spirv: &Spirv, stage: ShaderStage) -> Option<PushConstantRange> {
|
||||||
spirv
|
spirv
|
||||||
.iter_global()
|
.iter_global()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
&Instruction::TypePointer {
|
Instruction::TypePointer {
|
||||||
ty,
|
ty,
|
||||||
storage_class: StorageClass::PushConstant,
|
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 start = offset_of_struct(spirv, ty);
|
||||||
let end =
|
let end =
|
||||||
size_of_type(spirv, ty).expect("Found runtime-sized push constants") as u32;
|
size_of_type(spirv, ty).expect("Found runtime-sized push constants") as u32;
|
||||||
|
|
||||||
Some(PushConstantRange {
|
Some(PushConstantRange {
|
||||||
stages: stage.into(),
|
stages: stage.into(),
|
||||||
offset: start,
|
offset: start,
|
||||||
@ -964,39 +977,39 @@ fn specialization_constant_requirements(
|
|||||||
spirv
|
spirv
|
||||||
.iter_global()
|
.iter_global()
|
||||||
.filter_map(|instruction| {
|
.filter_map(|instruction| {
|
||||||
match instruction {
|
match *instruction {
|
||||||
&Instruction::SpecConstantTrue {
|
Instruction::SpecConstantTrue {
|
||||||
result_type_id,
|
result_type_id,
|
||||||
result_id,
|
result_id,
|
||||||
}
|
}
|
||||||
| &Instruction::SpecConstantFalse {
|
| Instruction::SpecConstantFalse {
|
||||||
result_type_id,
|
result_type_id,
|
||||||
result_id,
|
result_id,
|
||||||
}
|
}
|
||||||
| &Instruction::SpecConstant {
|
| Instruction::SpecConstant {
|
||||||
result_type_id,
|
result_type_id,
|
||||||
result_id,
|
result_id,
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
| &Instruction::SpecConstantComposite {
|
| Instruction::SpecConstantComposite {
|
||||||
result_type_id,
|
result_type_id,
|
||||||
result_id,
|
result_id,
|
||||||
..
|
..
|
||||||
} => spirv
|
} => spirv
|
||||||
.id(result_id)
|
.id(result_id)
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration:
|
decoration:
|
||||||
Decoration::SpecId {
|
Decoration::SpecId {
|
||||||
specialization_constant_id,
|
specialization_constant_id,
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
} => Some(*specialization_constant_id),
|
} => Some(specialization_constant_id),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.map(|constant_id| {
|
.map(|constant_id| {
|
||||||
let size = match spirv.id(result_type_id).instruction() {
|
let size = match *spirv.id(result_type_id).instruction() {
|
||||||
Instruction::TypeBool { .. } => {
|
Instruction::TypeBool { .. } => {
|
||||||
// Translate bool to Bool32
|
// Translate bool to Bool32
|
||||||
std::mem::size_of::<ash::vk::Bool32>() as DeviceSize
|
std::mem::size_of::<ash::vk::Bool32>() as DeviceSize
|
||||||
@ -1022,13 +1035,13 @@ fn shader_interface(
|
|||||||
let elements: Vec<_> = interface
|
let elements: Vec<_> = interface
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|&id| {
|
.filter_map(|&id| {
|
||||||
let (result_type_id, result_id) = match spirv.id(id).instruction() {
|
let (result_type_id, result_id) = match *spirv.id(id).instruction() {
|
||||||
&Instruction::Variable {
|
Instruction::Variable {
|
||||||
result_type_id,
|
result_type_id,
|
||||||
result_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,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1040,18 +1053,18 @@ fn shader_interface(
|
|||||||
|
|
||||||
let name = id_info
|
let name = id_info
|
||||||
.iter_name()
|
.iter_name()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Name { name, .. } => Some(Cow::Owned(name.to_owned())),
|
Instruction::Name { ref name, .. } => Some(Cow::Owned(name.clone())),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
|
|
||||||
let location = id_info
|
let location = id_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration: Decoration::Location { location },
|
decoration: Decoration::Location { location },
|
||||||
..
|
..
|
||||||
} => Some(*location),
|
} => Some(location),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
@ -1062,17 +1075,18 @@ fn shader_interface(
|
|||||||
});
|
});
|
||||||
let component = id_info
|
let component = id_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration: Decoration::Component { component },
|
decoration: Decoration::Component { component },
|
||||||
..
|
..
|
||||||
} => Some(*component),
|
} => Some(component),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let ty = shader_interface_type_of(spirv, result_type_id, ignore_first_array);
|
let ty = shader_interface_type_of(spirv, result_type_id, ignore_first_array);
|
||||||
assert!(ty.num_elements >= 1);
|
assert!(ty.num_elements >= 1);
|
||||||
|
|
||||||
Some(ShaderInterfaceEntry {
|
Some(ShaderInterfaceEntry {
|
||||||
location,
|
location,
|
||||||
component,
|
component,
|
||||||
@ -1111,21 +1125,21 @@ fn shader_interface(
|
|||||||
fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
|
fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
|
||||||
let id_info = spirv.id(id);
|
let id_info = spirv.id(id);
|
||||||
|
|
||||||
match id_info.instruction() {
|
match *id_info.instruction() {
|
||||||
Instruction::TypeBool { .. } => {
|
Instruction::TypeBool { .. } => {
|
||||||
panic!("Can't put booleans in structs")
|
panic!("Can't put booleans in structs")
|
||||||
}
|
}
|
||||||
Instruction::TypeInt { width, .. } | Instruction::TypeFloat { width, .. } => {
|
Instruction::TypeInt { width, .. } | Instruction::TypeFloat { width, .. } => {
|
||||||
assert!(width % 8 == 0);
|
assert!(width % 8 == 0);
|
||||||
Some(*width as DeviceSize / 8)
|
Some(width as DeviceSize / 8)
|
||||||
}
|
}
|
||||||
&Instruction::TypeVector {
|
Instruction::TypeVector {
|
||||||
component_type,
|
component_type,
|
||||||
component_count,
|
component_count,
|
||||||
..
|
..
|
||||||
} => size_of_type(spirv, component_type)
|
} => size_of_type(spirv, component_type)
|
||||||
.map(|component_size| component_size * component_count as DeviceSize),
|
.map(|component_size| component_size * component_count as DeviceSize),
|
||||||
&Instruction::TypeMatrix {
|
Instruction::TypeMatrix {
|
||||||
column_type,
|
column_type,
|
||||||
column_count,
|
column_count,
|
||||||
..
|
..
|
||||||
@ -1134,19 +1148,19 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
|
|||||||
size_of_type(spirv, column_type)
|
size_of_type(spirv, column_type)
|
||||||
.map(|column_size| column_size * column_count as DeviceSize)
|
.map(|column_size| column_size * column_count as DeviceSize)
|
||||||
}
|
}
|
||||||
&Instruction::TypeArray { length, .. } => {
|
Instruction::TypeArray { length, .. } => {
|
||||||
let stride = id_info
|
let stride = id_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::Decorate {
|
Instruction::Decorate {
|
||||||
decoration: Decoration::ArrayStride { array_stride },
|
decoration: Decoration::ArrayStride { array_stride },
|
||||||
..
|
..
|
||||||
} => Some(*array_stride),
|
} => Some(array_stride),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let length = match spirv.id(length).instruction() {
|
let length = match spirv.id(length).instruction() {
|
||||||
&Instruction::Constant { ref value, .. } => Some(
|
Instruction::Constant { value, .. } => Some(
|
||||||
value
|
value
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -1159,7 +1173,9 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option<DeviceSize> {
|
|||||||
Some(stride as DeviceSize * length)
|
Some(stride as DeviceSize * length)
|
||||||
}
|
}
|
||||||
Instruction::TypeRuntimeArray { .. } => None,
|
Instruction::TypeRuntimeArray { .. } => None,
|
||||||
Instruction::TypeStruct { member_types, .. } => {
|
Instruction::TypeStruct {
|
||||||
|
ref member_types, ..
|
||||||
|
} => {
|
||||||
let mut end_of_struct = 0;
|
let mut end_of_struct = 0;
|
||||||
|
|
||||||
for (&member, member_info) in member_types.iter().zip(id_info.iter_members()) {
|
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 =
|
let offset =
|
||||||
member_info
|
member_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::MemberDecorate {
|
Instruction::MemberDecorate {
|
||||||
decoration: Decoration::Offset { byte_offset },
|
decoration: Decoration::Offset { byte_offset },
|
||||||
..
|
..
|
||||||
} => Some(*byte_offset),
|
} => Some(byte_offset),
|
||||||
_ => None,
|
_ => None,
|
||||||
})?;
|
})?;
|
||||||
let size = size_of_type(spirv, member)?;
|
let size = size_of_type(spirv, member)?;
|
||||||
@ -1206,11 +1222,11 @@ fn offset_of_struct(spirv: &Spirv, id: Id) -> u32 {
|
|||||||
.filter_map(|member_info| {
|
.filter_map(|member_info| {
|
||||||
member_info
|
member_info
|
||||||
.iter_decoration()
|
.iter_decoration()
|
||||||
.find_map(|instruction| match instruction {
|
.find_map(|instruction| match *instruction {
|
||||||
Instruction::MemberDecorate {
|
Instruction::MemberDecorate {
|
||||||
decoration: Decoration::Offset { byte_offset },
|
decoration: Decoration::Offset { byte_offset },
|
||||||
..
|
..
|
||||||
} => Some(*byte_offset),
|
} => Some(byte_offset),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -1293,15 +1309,14 @@ fn shader_interface_type_of(
|
|||||||
let num_elements = spirv
|
let num_elements = spirv
|
||||||
.instructions()
|
.instructions()
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|e| match e {
|
.find_map(|instruction| match *instruction {
|
||||||
&Instruction::Constant {
|
Instruction::Constant {
|
||||||
result_id,
|
result_id,
|
||||||
ref value,
|
ref value,
|
||||||
..
|
..
|
||||||
} if result_id == length => Some(value.clone()),
|
} if result_id == length => Some(value.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
.next()
|
|
||||||
.expect("failed to find array length")
|
.expect("failed to find array length")
|
||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
@ -1351,25 +1366,19 @@ fn is_builtin(spirv: &Spirv, id: Id) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
match id_info.instruction() {
|
match id_info.instruction() {
|
||||||
Instruction::Variable { result_type_id, .. } => {
|
Instruction::Variable {
|
||||||
return is_builtin(spirv, *result_type_id);
|
result_type_id: ty, ..
|
||||||
}
|
}
|
||||||
Instruction::TypeArray { element_type, .. } => {
|
| Instruction::TypeArray {
|
||||||
return is_builtin(spirv, *element_type);
|
element_type: ty, ..
|
||||||
}
|
}
|
||||||
Instruction::TypeRuntimeArray { element_type, .. } => {
|
| Instruction::TypeRuntimeArray {
|
||||||
return is_builtin(spirv, *element_type);
|
element_type: ty, ..
|
||||||
}
|
}
|
||||||
|
| Instruction::TypePointer { ty, .. } => is_builtin(spirv, *ty),
|
||||||
Instruction::TypeStruct { member_types, .. } => {
|
Instruction::TypeStruct { member_types, .. } => {
|
||||||
if member_types.iter().any(|ty| is_builtin(spirv, *ty)) {
|
member_types.iter().any(|ty| is_builtin(spirv, *ty))
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Instruction::TypePointer { ty, .. } => {
|
_ => false,
|
||||||
return is_builtin(spirv, *ty);
|
|
||||||
}
|
|
||||||
_ => (),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
@ -571,6 +571,7 @@ impl From<Id> for u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Id {
|
impl Display for Id {
|
||||||
|
#[inline]
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(f, "%{}", self.0)
|
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
|
/// 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
|
/// word. `instruction` is the number of the instruction currently being read, and is used for
|
||||||
/// error reporting.
|
/// error reporting.
|
||||||
#[inline]
|
|
||||||
fn new(words: &'a [u32], instruction: usize) -> Self {
|
fn new(words: &'a [u32], instruction: usize) -> Self {
|
||||||
debug_assert!(!words.is_empty());
|
debug_assert!(!words.is_empty());
|
||||||
Self {
|
Self {
|
||||||
@ -599,13 +599,11 @@ impl<'a> InstructionReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether the reader has reached the end of the current instruction.
|
/// Returns whether the reader has reached the end of the current instruction.
|
||||||
#[inline]
|
|
||||||
fn is_empty(&self) -> bool {
|
fn is_empty(&self) -> bool {
|
||||||
self.next_word >= self.words.len()
|
self.next_word >= self.words.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts the `ParseErrors` enum to the `ParseError` struct, adding contextual information.
|
/// Converts the `ParseErrors` enum to the `ParseError` struct, adding contextual information.
|
||||||
#[inline]
|
|
||||||
fn map_err(&self, error: ParseErrors) -> ParseError {
|
fn map_err(&self, error: ParseErrors) -> ParseError {
|
||||||
ParseError {
|
ParseError {
|
||||||
instruction: self.instruction,
|
instruction: self.instruction,
|
||||||
@ -616,7 +614,6 @@ impl<'a> InstructionReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the next word in the sequence.
|
/// Returns the next word in the sequence.
|
||||||
#[inline]
|
|
||||||
fn next_u32(&mut self) -> Result<u32, ParseError> {
|
fn next_u32(&mut self) -> Result<u32, ParseError> {
|
||||||
let word = *self.words.get(self.next_word).ok_or(ParseError {
|
let word = *self.words.get(self.next_word).ok_or(ParseError {
|
||||||
instruction: self.instruction,
|
instruction: self.instruction,
|
||||||
@ -625,6 +622,7 @@ impl<'a> InstructionReader<'a> {
|
|||||||
words: self.words.to_owned(),
|
words: self.words.to_owned(),
|
||||||
})?;
|
})?;
|
||||||
self.next_word += 1;
|
self.next_word += 1;
|
||||||
|
|
||||||
Ok(word)
|
Ok(word)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -653,7 +651,6 @@ impl<'a> InstructionReader<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Reads all remaining words.
|
/// Reads all remaining words.
|
||||||
#[inline]
|
|
||||||
fn remainder(&mut self) -> Vec<u32> {
|
fn remainder(&mut self) -> Vec<u32> {
|
||||||
let vec = self.words[self.next_word..].to_owned();
|
let vec = self.words[self.next_word..].to_owned();
|
||||||
self.next_word = self.words.len();
|
self.next_word = self.words.len();
|
||||||
@ -686,13 +683,12 @@ pub enum SpirvError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SpirvError {
|
impl Display for SpirvError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::BadLayout { index } => write!(
|
Self::BadLayout { index } => write!(
|
||||||
f,
|
f,
|
||||||
"the instruction at index {} does not follow the logical layout of a module",
|
"the instruction at index {} does not follow the logical layout of a module",
|
||||||
index
|
index,
|
||||||
),
|
),
|
||||||
Self::DuplicateId {
|
Self::DuplicateId {
|
||||||
id,
|
id,
|
||||||
@ -701,10 +697,19 @@ impl Display for SpirvError {
|
|||||||
} => write!(
|
} => write!(
|
||||||
f,
|
f,
|
||||||
"id {} is assigned more than once, by instructions {} and {}",
|
"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::InvalidHeader => write!(f, "the SPIR-V module header is invalid"),
|
||||||
Self::MemoryModelInvalid => {
|
Self::MemoryModelInvalid => {
|
||||||
write!(f, "the MemoryModel instruction is not present exactly once")
|
write!(f, "the MemoryModel instruction is not present exactly once")
|
||||||
@ -715,7 +720,6 @@ impl Display for SpirvError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for SpirvError {
|
impl Error for SpirvError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
Self::ParseError(err) => Some(err),
|
Self::ParseError(err) => Some(err),
|
||||||
@ -725,7 +729,6 @@ impl Error for SpirvError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<ParseError> for SpirvError {
|
impl From<ParseError> for SpirvError {
|
||||||
#[inline]
|
|
||||||
fn from(err: ParseError) -> Self {
|
fn from(err: ParseError) -> Self {
|
||||||
Self::ParseError(err)
|
Self::ParseError(err)
|
||||||
}
|
}
|
||||||
@ -745,12 +748,11 @@ pub struct ParseError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for ParseError {
|
impl Display for ParseError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"at instruction {}, word {}: {}",
|
"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 {
|
impl Display for ParseErrors {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::FromUtf8Error(_) => write!(f, "invalid UTF-8 in string literal"),
|
Self::FromUtf8Error(_) => write!(f, "invalid UTF-8 in string literal"),
|
||||||
Self::LeftoverOperands => write!(f, "unparsed operands remaining"),
|
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::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::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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,10 +142,9 @@ impl DisplayPlane {
|
|||||||
|
|
||||||
/// Enumerates all the display planes that are available on a given physical device.
|
/// 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.
|
/// - Panics if the device or host ran out of memory.
|
||||||
///
|
|
||||||
// TODO: move iterator creation here from raw constructor?
|
// TODO: move iterator creation here from raw constructor?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<DisplayPlane> {
|
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.
|
/// Enumerates all the displays that are available on a given physical device.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the device or host ran out of memory.
|
/// - Panics if the device or host ran out of memory.
|
||||||
///
|
|
||||||
// TODO: move iterator creation here from raw constructor?
|
// TODO: move iterator creation here from raw constructor?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<Display> {
|
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.
|
/// Returns a list of all modes available on this display.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the device or host ran out of memory.
|
/// - Panics if the device or host ran out of memory.
|
||||||
///
|
|
||||||
// TODO: move iterator creation here from display_modes_raw?
|
// TODO: move iterator creation here from display_modes_raw?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn display_modes(&self) -> IntoIter<DisplayMode> {
|
pub fn display_modes(&self) -> IntoIter<DisplayMode> {
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
//! may be able to do this for you, if you pass it ownership of your Window (or a
|
//! may be able to do this for you, if you pass it ownership of your Window (or a
|
||||||
//! reference-counting container for it).
|
//! reference-counting container for it).
|
||||||
//!
|
//!
|
||||||
//! ### Example
|
//! ### Examples
|
||||||
//!
|
//!
|
||||||
//! ```no_run
|
//! ```no_run
|
||||||
//! use std::ptr;
|
//! use std::ptr;
|
||||||
@ -88,9 +88,9 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! #
|
//! #
|
||||||
//! # fn build_window() -> Arc<Window> { Arc::new(Window(ptr::null())) }
|
//! # 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 _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()
|
//! Surface::from_win32(instance.clone(), hinstance, window.hwnd(), Arc::clone(&window)).unwrap()
|
||||||
//! };
|
//! };
|
||||||
//! ```
|
//! ```
|
||||||
@ -194,31 +194,31 @@
|
|||||||
//!
|
//!
|
||||||
//! // Create the swapchain and its images.
|
//! // Create the swapchain and its images.
|
||||||
//! let (swapchain, images) = Swapchain::new(
|
//! let (swapchain, images) = Swapchain::new(
|
||||||
//! // Create the swapchain in this `device`'s memory.
|
//! // Create the swapchain in this `device`'s memory.
|
||||||
//! device,
|
//! device,
|
||||||
//! // The surface where the images will be presented.
|
//! // The surface where the images will be presented.
|
||||||
//! surface,
|
//! surface,
|
||||||
//! // The creation parameters.
|
//! // The creation parameters.
|
||||||
//! SwapchainCreateInfo {
|
//! SwapchainCreateInfo {
|
||||||
//! // How many images to use in the swapchain.
|
//! // How many images to use in the swapchain.
|
||||||
//! min_image_count,
|
//! min_image_count,
|
||||||
//! // The format of the images.
|
//! // The format of the images.
|
||||||
//! image_format: Some(image_format),
|
//! image_format: Some(image_format),
|
||||||
//! // The size of each image.
|
//! // The size of each image.
|
||||||
//! image_extent,
|
//! image_extent,
|
||||||
//! // What the images are going to be used for.
|
//! // What the images are going to be used for.
|
||||||
//! image_usage,
|
//! image_usage,
|
||||||
//! // What transformation to use with the surface.
|
//! // What transformation to use with the surface.
|
||||||
//! pre_transform,
|
//! pre_transform,
|
||||||
//! // How to handle the alpha channel.
|
//! // How to handle the alpha channel.
|
||||||
//! composite_alpha,
|
//! composite_alpha,
|
||||||
//! // How to present images.
|
//! // How to present images.
|
||||||
//! present_mode,
|
//! present_mode,
|
||||||
//! // How to handle full-screen exclusivity
|
//! // How to handle full-screen exclusivity
|
||||||
//! full_screen_exclusive,
|
//! full_screen_exclusive,
|
||||||
//! ..Default::default()
|
//! ..Default::default()
|
||||||
//! }
|
//! }
|
||||||
//! )?;
|
//! )?;
|
||||||
//!
|
//!
|
||||||
//! # Ok(())
|
//! # Ok(())
|
||||||
//! # }
|
//! # }
|
||||||
@ -256,12 +256,14 @@
|
|||||||
//! // The command_buffer contains the draw commands that modify the framebuffer
|
//! // The command_buffer contains the draw commands that modify the framebuffer
|
||||||
//! // constructed from images[image_index]
|
//! // constructed from images[image_index]
|
||||||
//! acquire_future
|
//! acquire_future
|
||||||
//! .then_execute(queue.clone(), command_buffer).unwrap()
|
//! .then_execute(queue.clone(), command_buffer)
|
||||||
|
//! .unwrap()
|
||||||
//! .then_swapchain_present(
|
//! .then_swapchain_present(
|
||||||
//! queue.clone(),
|
//! queue.clone(),
|
||||||
//! SwapchainPresentInfo::swapchain_image_index(swapchain.clone(), image_index),
|
//! 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
|
//! rendering, you will need to *recreate* the swapchain by creating a new swapchain and passing
|
||||||
//! as last parameter the old swapchain.
|
//! as last parameter the old swapchain.
|
||||||
//!
|
//!
|
||||||
//!
|
|
||||||
//! ```
|
//! ```
|
||||||
//! use vulkano::swapchain;
|
//! use vulkano::swapchain;
|
||||||
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo, SwapchainPresentInfo};
|
//! use vulkano::swapchain::{AcquireError, SwapchainCreateInfo, SwapchainPresentInfo};
|
||||||
@ -303,7 +304,7 @@
|
|||||||
//! let (image_index, suboptimal, acq_future) = match swapchain::acquire_next_image(swapchain.clone(), None) {
|
//! let (image_index, suboptimal, acq_future) = match swapchain::acquire_next_image(swapchain.clone(), None) {
|
||||||
//! Ok(r) => r,
|
//! Ok(r) => r,
|
||||||
//! Err(AcquireError::OutOfDate) => { recreate_swapchain = true; continue; },
|
//! Err(AcquireError::OutOfDate) => { recreate_swapchain = true; continue; },
|
||||||
//! Err(err) => panic!("{:?}", err)
|
//! Err(err) => panic!("{:?}", err),
|
||||||
//! };
|
//! };
|
||||||
//!
|
//!
|
||||||
//! // ...
|
//! // ...
|
||||||
@ -314,14 +315,14 @@
|
|||||||
//! queue.clone(),
|
//! queue.clone(),
|
||||||
//! SwapchainPresentInfo::swapchain_image_index(swapchain.clone(), image_index),
|
//! 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 {
|
//! if suboptimal {
|
||||||
//! recreate_swapchain = true;
|
//! recreate_swapchain = true;
|
||||||
//! }
|
//! }
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
surface::{
|
surface::{
|
||||||
@ -448,10 +449,12 @@ pub struct RectangleLayer {
|
|||||||
|
|
||||||
impl RectangleLayer {
|
impl RectangleLayer {
|
||||||
/// Returns true if this rectangle layer is compatible with swapchain.
|
/// Returns true if this rectangle layer is compatible with swapchain.
|
||||||
|
#[inline]
|
||||||
pub fn is_compatible_with(&self, swapchain: &dyn SwapchainAbstract) -> bool {
|
pub fn is_compatible_with(&self, swapchain: &dyn SwapchainAbstract) -> bool {
|
||||||
// FIXME negative offset is not disallowed by spec, but semantically should not be possible
|
// FIXME negative offset is not disallowed by spec, but semantically should not be possible
|
||||||
debug_assert!(self.offset[0] >= 0);
|
debug_assert!(self.offset[0] >= 0);
|
||||||
debug_assert!(self.offset[1] >= 0);
|
debug_assert!(self.offset[1] >= 0);
|
||||||
|
|
||||||
self.offset[0] as u32 + self.extent[0] <= swapchain.image_extent()[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.offset[1] as u32 + self.extent[1] <= swapchain.image_extent()[1]
|
||||||
&& self.layer < swapchain.image_array_layers()
|
&& self.layer < swapchain.image_array_layers()
|
||||||
|
@ -67,7 +67,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `handle` must have been created from `api`.
|
/// - `handle` must have been created from `api`.
|
||||||
/// - The window object that `handle` was created from must outlive the created `Surface`.
|
/// - The window object that `handle` was created from must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
handle: ash::vk::SurfaceKHR,
|
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,
|
/// 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.
|
/// 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> {
|
pub fn headless(instance: Arc<Instance>, win: W) -> Result<Arc<Self>, SurfaceCreationError> {
|
||||||
Self::validate_headless(&instance)?;
|
Self::validate_headless(&instance)?;
|
||||||
|
|
||||||
@ -159,11 +157,10 @@ impl<W> Surface<W> {
|
|||||||
|
|
||||||
/// Creates a `Surface` from a `DisplayPlane`.
|
/// Creates a `Surface` from a `DisplayPlane`.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `display_mode` and `plane` don't belong to the same physical device.
|
/// - 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`.
|
/// - Panics if `plane` doesn't support the display of `display_mode`.
|
||||||
#[inline]
|
|
||||||
pub fn from_display_plane(
|
pub fn from_display_plane(
|
||||||
display_mode: &DisplayMode,
|
display_mode: &DisplayMode,
|
||||||
plane: &DisplayPlane,
|
plane: &DisplayPlane,
|
||||||
@ -263,7 +260,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `window` must be a valid Android `ANativeWindow` handle.
|
/// - `window` must be a valid Android `ANativeWindow` handle.
|
||||||
/// - The object referred to by `window` must outlive the created `Surface`.
|
/// - The object referred to by `window` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_android<T>(
|
pub unsafe fn from_android<T>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: *const T,
|
window: *const T,
|
||||||
@ -345,7 +341,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `surface` must be a valid DirectFB `IDirectFBSurface` handle.
|
/// - `surface` must be a valid DirectFB `IDirectFBSurface` handle.
|
||||||
/// - The object referred to by `dfb` and `surface` must outlive the created `Surface`.
|
/// - The object referred to by `dfb` and `surface` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_directfb<D, S>(
|
pub unsafe fn from_directfb<D, S>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
dfb: *const D,
|
dfb: *const D,
|
||||||
@ -433,7 +428,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `image_pipe_handle` must be a valid Fuchsia `zx_handle_t` handle.
|
/// - `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 object referred to by `image_pipe_handle` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_fuchsia_image_pipe(
|
pub unsafe fn from_fuchsia_image_pipe(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
image_pipe_handle: ash::vk::zx_handle_t,
|
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.
|
/// - `stream_descriptor` must be a valid Google Games Platform `GgpStreamDescriptor` handle.
|
||||||
/// - The object referred to by `stream_descriptor` must outlive the created `Surface`.
|
/// - The object referred to by `stream_descriptor` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_ggp_stream_descriptor(
|
pub unsafe fn from_ggp_stream_descriptor(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
stream_descriptor: ash::vk::GgpStreamDescriptor,
|
||||||
@ -607,7 +600,6 @@ impl<W> Surface<W> {
|
|||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
/// - The `UIView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_ios(
|
pub unsafe fn from_ios(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
metal_layer: IOSMetalLayer,
|
metal_layer: IOSMetalLayer,
|
||||||
@ -694,7 +686,6 @@ impl<W> Surface<W> {
|
|||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
/// - The `NSView` must be backed by a `CALayer` instance of type `CAMetalLayer`.
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_mac_os<T>(
|
pub unsafe fn from_mac_os<T>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
view: *const T,
|
view: *const T,
|
||||||
@ -780,7 +771,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `layer` must be a valid Metal `CAMetalLayer` handle.
|
/// - `layer` must be a valid Metal `CAMetalLayer` handle.
|
||||||
/// - The object referred to by `layer` must outlive the created `Surface`.
|
/// - The object referred to by `layer` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_metal<T>(
|
pub unsafe fn from_metal<T>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
layer: *const T,
|
layer: *const T,
|
||||||
@ -859,7 +849,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `window` must be a valid QNX Screen `_screen_window` handle.
|
/// - `window` must be a valid QNX Screen `_screen_window` handle.
|
||||||
/// - The object referred to by `window` must outlive the created `Surface`.
|
/// - The object referred to by `window` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_qnx_screen<T, U>(
|
pub unsafe fn from_qnx_screen<T, U>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
context: *const T,
|
context: *const T,
|
||||||
@ -949,7 +938,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `window` must be a valid `nn::vi::NativeWindowHandle` handle.
|
/// - `window` must be a valid `nn::vi::NativeWindowHandle` handle.
|
||||||
/// - The object referred to by `window` must outlive the created `Surface`.
|
/// - The object referred to by `window` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_vi<T>(
|
pub unsafe fn from_vi<T>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
window: *const T,
|
window: *const T,
|
||||||
@ -1033,7 +1021,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `surface` must be a valid Wayland `wl_surface` handle.
|
/// - `surface` must be a valid Wayland `wl_surface` handle.
|
||||||
/// - The objects referred to by `display` and `surface` must outlive the created `Surface`.
|
/// - The objects referred to by `display` and `surface` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_wayland<D, S>(
|
pub unsafe fn from_wayland<D, S>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
display: *const D,
|
display: *const D,
|
||||||
@ -1126,7 +1113,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `hwnd` must be a valid Win32 `HWND` handle.
|
/// - `hwnd` must be a valid Win32 `HWND` handle.
|
||||||
/// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`.
|
/// - The objects referred to by `hwnd` and `hinstance` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_win32<T, U>(
|
pub unsafe fn from_win32<T, U>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
hinstance: *const T,
|
hinstance: *const T,
|
||||||
@ -1217,7 +1203,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `window` must be a valid X11 `xcb_window_t` handle.
|
/// - `window` must be a valid X11 `xcb_window_t` handle.
|
||||||
/// - The objects referred to by `connection` and `window` must outlive the created `Surface`.
|
/// - The objects referred to by `connection` and `window` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_xcb<C>(
|
pub unsafe fn from_xcb<C>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
connection: *const C,
|
connection: *const C,
|
||||||
@ -1308,7 +1293,6 @@ impl<W> Surface<W> {
|
|||||||
/// - `window` must be a valid Xlib `Window` handle.
|
/// - `window` must be a valid Xlib `Window` handle.
|
||||||
/// - The objects referred to by `display` and `window` must outlive the created `Surface`.
|
/// - The objects referred to by `display` and `window` must outlive the created `Surface`.
|
||||||
/// The `win` parameter can be used to ensure this.
|
/// The `win` parameter can be used to ensure this.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn from_xlib<D>(
|
pub unsafe fn from_xlib<D>(
|
||||||
instance: Arc<Instance>,
|
instance: Arc<Instance>,
|
||||||
display: *const D,
|
display: *const D,
|
||||||
@ -1390,19 +1374,16 @@ impl<W> Surface<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the instance this surface was created with.
|
/// Returns the instance this surface was created with.
|
||||||
#[inline]
|
|
||||||
pub fn instance(&self) -> &Arc<Instance> {
|
pub fn instance(&self) -> &Arc<Instance> {
|
||||||
&self.instance
|
&self.instance
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the windowing API that was used to construct the surface.
|
/// Returns the windowing API that was used to construct the surface.
|
||||||
#[inline]
|
|
||||||
pub fn api(&self) -> SurfaceApi {
|
pub fn api(&self) -> SurfaceApi {
|
||||||
self.api
|
self.api
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a reference to the `W` type parameter that was passed when creating the surface.
|
/// Returns a reference to the `W` type parameter that was passed when creating the surface.
|
||||||
#[inline]
|
|
||||||
pub fn window(&self) -> &W {
|
pub fn window(&self) -> &W {
|
||||||
&self.window
|
&self.window
|
||||||
}
|
}
|
||||||
@ -1415,7 +1396,6 @@ impl<W> Surface<W> {
|
|||||||
/// its sublayers are not automatically resized, and we must resize
|
/// its sublayers are not automatically resized, and we must resize
|
||||||
/// it here.
|
/// it here.
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn update_ios_sublayer_on_resize(&self) {
|
pub unsafe fn update_ios_sublayer_on_resize(&self) {
|
||||||
use core_graphics_types::geometry::CGRect;
|
use core_graphics_types::geometry::CGRect;
|
||||||
let class = class!(CAMetalLayer);
|
let class = class!(CAMetalLayer);
|
||||||
@ -1427,7 +1407,6 @@ impl<W> Surface<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Drop for Surface<W> {
|
impl<W> Drop for Surface<W> {
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fns = self.instance.fns();
|
let fns = self.instance.fns();
|
||||||
@ -1443,14 +1422,12 @@ impl<W> Drop for Surface<W> {
|
|||||||
unsafe impl<W> VulkanObject for Surface<W> {
|
unsafe impl<W> VulkanObject for Surface<W> {
|
||||||
type Object = ash::vk::SurfaceKHR;
|
type Object = ash::vk::SurfaceKHR;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn internal_object(&self) -> ash::vk::SurfaceKHR {
|
fn internal_object(&self) -> ash::vk::SurfaceKHR {
|
||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Debug for Surface<W> {
|
impl<W> Debug for Surface<W> {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
let Self {
|
let Self {
|
||||||
handle,
|
handle,
|
||||||
@ -1472,7 +1449,6 @@ impl<W> Debug for Surface<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W> PartialEq for Surface<W> {
|
impl<W> PartialEq for Surface<W> {
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.instance() == other.instance()
|
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> Eq for Surface<W> {}
|
||||||
|
|
||||||
impl<W> Hash for Surface<W> {
|
impl<W> Hash for Surface<W> {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.instance().hash(state);
|
self.instance().hash(state);
|
||||||
@ -1489,7 +1464,6 @@ impl<W> Hash for Surface<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<W> SurfaceSwapchainLock for Surface<W> {
|
unsafe impl<W> SurfaceSwapchainLock for Surface<W> {
|
||||||
#[inline]
|
|
||||||
fn flag(&self) -> &AtomicBool {
|
fn flag(&self) -> &AtomicBool {
|
||||||
&self.has_swapchain
|
&self.has_swapchain
|
||||||
}
|
}
|
||||||
@ -1508,7 +1482,6 @@ pub enum SurfaceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for SurfaceCreationError {
|
impl Error for SurfaceCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
SurfaceCreationError::OomError(err) => Some(err),
|
SurfaceCreationError::OomError(err) => Some(err),
|
||||||
@ -1518,11 +1491,9 @@ impl Error for SurfaceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SurfaceCreationError {
|
impl Display for SurfaceCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
SurfaceCreationError::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1536,14 +1507,12 @@ impl Display for SurfaceCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for SurfaceCreationError {
|
impl From<OomError> for SurfaceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> SurfaceCreationError {
|
fn from(err: OomError) -> SurfaceCreationError {
|
||||||
SurfaceCreationError::OomError(err)
|
SurfaceCreationError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for SurfaceCreationError {
|
impl From<VulkanError> for SurfaceCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> SurfaceCreationError {
|
fn from(err: VulkanError) -> SurfaceCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -1805,83 +1774,87 @@ vulkan_enum! {
|
|||||||
///
|
///
|
||||||
/// ## What is a color space?
|
/// ## What is a color space?
|
||||||
///
|
///
|
||||||
/// Each pixel of a monitor is made of three components: one red, one green, and one blue. In the
|
/// Each pixel of a monitor is made of three components: one red, one green, and one blue. In
|
||||||
/// past, computers would simply send to the monitor the intensity of each of the three components.
|
/// 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
|
/// This proved to be problematic, because depending on the brand of the monitor the colors
|
||||||
/// not exactly be the same. For example on some monitors, a value of `[1.0, 0.0, 0.0]` would be a
|
/// 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.
|
/// bit more orange than on others.
|
||||||
///
|
///
|
||||||
/// In order to standardize this, there exist what are called *color spaces*: sRGB, AdobeRGB,
|
/// 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
|
/// DCI-P3, scRGB, etc. When you manipulate RGB values in a specific color space, these values
|
||||||
/// a precise absolute meaning in terms of color, that is the same across all systems and monitors.
|
/// 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
|
/// > **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
|
/// > representation of the data, but not how it is interpreted. You can think of this a bit
|
||||||
/// > text encoding. An *RGB* value is a like a byte, in other words it is the medium by which
|
/// > like text encoding. An *RGB* value is a like a byte, in other words it is the medium by
|
||||||
/// > values are communicated, and a *color space* is like a text encoding (eg. UTF-8), in other
|
/// > which values are communicated, and a *color space* is like a text encoding (eg. UTF-8),
|
||||||
/// > words it is the way the value should be interpreted.
|
/// > 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,
|
/// 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.
|
/// and most images files are encoded in this color space.
|
||||||
///
|
///
|
||||||
/// ## Pixel formats and linear vs non-linear
|
/// ## 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
|
/// In Vulkan all images have a specific format in which the data is stored. The data of an
|
||||||
/// consists of pixels in RGB but contains no information about the color space (or lack thereof)
|
/// image consists of pixels in RGB but contains no information about the color space (or lack
|
||||||
/// of these pixels. You are free to store them in whatever color space you want.
|
/// 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
|
/// But one big practical problem with color spaces is that they are sometimes not linear, and
|
||||||
/// particular the popular sRGB color space is not linear. In a non-linear color space, a value of
|
/// in particular the popular sRGB color space is not linear. In a non-linear color space, a
|
||||||
/// `[0.6, 0.6, 0.6]` for example is **not** twice as bright as a value of `[0.3, 0.3, 0.3]`. This
|
/// value of `[0.6, 0.6, 0.6]` for example is **not** twice as bright as a value of `[0.3, 0.3,
|
||||||
/// is problematic, because operations such as taking the average of two colors or calculating the
|
/// 0.3]`. This is problematic, because operations such as taking the average of two colors or
|
||||||
/// lighting of a texture with a dot product are mathematically incorrect and will produce
|
/// calculating the lighting of a texture with a dot product are mathematically incorrect and
|
||||||
/// incorrect colors.
|
/// will produce incorrect colors.
|
||||||
///
|
///
|
||||||
/// > **Note**: If the texture format has an alpha component, it is not affected by the color space
|
/// > **Note**: If the texture format has an alpha component, it is not affected by the color
|
||||||
/// > and always behaves linearly.
|
/// > space and always behaves linearly.
|
||||||
///
|
///
|
||||||
/// In order to solve this Vulkan also provides image formats with the `Srgb` suffix, which are
|
/// 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
|
/// 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
|
/// format from a shader, the implementation will automatically turn the pixel values into a
|
||||||
/// color space that is suitable for linear operations (such as additions or multiplications).
|
/// linear color space that is suitable for linear operations (such as additions or
|
||||||
/// When you write to a framebuffer attachment with such a format, the implementation will
|
/// multiplications). When you write to a framebuffer attachment with such a format, the
|
||||||
/// automatically perform the opposite conversion. These conversions are most of the time performed
|
/// implementation will automatically perform the opposite conversion. These conversions are
|
||||||
/// by the hardware and incur no additional cost.
|
/// most of the time performed by the hardware and incur no additional cost.
|
||||||
///
|
///
|
||||||
/// ## Color space of the swapchain
|
/// ## Color space of the swapchain
|
||||||
///
|
///
|
||||||
/// The color space that you specify when you create a swapchain is how the implementation will
|
/// The color space that you specify when you create a swapchain is how the implementation will
|
||||||
/// interpret the raw data inside of the image.
|
/// interpret the raw data inside of the image.
|
||||||
///
|
///
|
||||||
/// > **Note**: The implementation can choose to send the data in the swapchain image directly to
|
/// > **Note**: The implementation can choose to send the data in the swapchain image directly
|
||||||
/// > the monitor, but it can also choose to write it in an intermediary buffer that is then read
|
/// > to the monitor, but it can also choose to write it in an intermediary buffer that is then
|
||||||
/// > by the operating system or windowing system. Therefore the color space that the
|
/// > 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.
|
/// > 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
|
/// 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.
|
/// that is specified here, otherwise colors will be incorrect. The implementation will never
|
||||||
/// The implementation will never perform any additional automatic conversion after the colors have
|
/// perform any additional automatic conversion after the colors have been written to the
|
||||||
/// been written to the swapchain image.
|
/// swapchain image.
|
||||||
///
|
///
|
||||||
/// # How do I handle this correctly?
|
/// # How do I handle this correctly?
|
||||||
///
|
///
|
||||||
/// The easiest way to handle color spaces in a cross-platform program is:
|
/// The easiest way to handle color spaces in a cross-platform program is:
|
||||||
///
|
///
|
||||||
/// - Always request the `SrgbNonLinear` color space when creating the swapchain.
|
/// - 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
|
/// - Make sure that all your image files use the sRGB color space, and load them in images
|
||||||
/// format has the `Srgb` suffix. Only use non-sRGB image formats for intermediary computations
|
/// whose format has the `Srgb` suffix. Only use non-sRGB image formats for intermediary
|
||||||
/// or to store non-color data.
|
/// computations or to store non-color data.
|
||||||
/// - Swapchain images should have a format with the `Srgb` suffix.
|
/// - Swapchain images should have a format with the `Srgb` suffix.
|
||||||
///
|
///
|
||||||
/// > **Note**: Lots of developers are confused by color spaces. You can sometimes find articles
|
/// > **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
|
/// > 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.
|
/// > 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
|
/// Additionally you can try detect whether the implementation supports any additional color
|
||||||
/// and perform a manual conversion to that color space from inside your shader.
|
/// space and perform a manual conversion to that color space from inside your shader.
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
ColorSpace = ColorSpaceKHR(i32);
|
ColorSpace = ColorSpaceKHR(i32);
|
||||||
|
|
||||||
@ -1964,10 +1937,10 @@ vulkan_enum! {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parameters for
|
/// Parameters for [`PhysicalDevice::surface_capabilities`] and [`PhysicalDevice::surface_formats`].
|
||||||
/// [`PhysicalDevice::surface_capabilities`](crate::device::physical::PhysicalDevice::surface_capabilities)
|
///
|
||||||
/// and
|
/// [`PhysicalDevice::surface_capabilities`]: crate::device::physical::PhysicalDevice::surface_capabilities
|
||||||
/// [`PhysicalDevice::surface_formats`](crate::device::physical::PhysicalDevice::surface_formats).
|
/// [`PhysicalDevice::surface_formats`]: crate::device::physical::PhysicalDevice::surface_formats
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct SurfaceInfo {
|
pub struct SurfaceInfo {
|
||||||
pub full_screen_exclusive: FullScreenExclusive,
|
pub full_screen_exclusive: FullScreenExclusive,
|
||||||
@ -2004,6 +1977,7 @@ pub struct IOSMetalLayer {
|
|||||||
|
|
||||||
#[cfg(target_os = "ios")]
|
#[cfg(target_os = "ios")]
|
||||||
impl IOSMetalLayer {
|
impl IOSMetalLayer {
|
||||||
|
#[inline]
|
||||||
pub fn new(main_layer: *mut Object, render_layer: *mut Object) -> Self {
|
pub fn new(main_layer: *mut Object, render_layer: *mut Object) -> Self {
|
||||||
Self {
|
Self {
|
||||||
main_layer: LayerHandle(main_layer),
|
main_layer: LayerHandle(main_layer),
|
||||||
|
@ -71,8 +71,9 @@ pub struct Swapchain<W> {
|
|||||||
// The images of this swapchain.
|
// The images of this swapchain.
|
||||||
images: Vec<ImageEntry>,
|
images: Vec<ImageEntry>,
|
||||||
|
|
||||||
// If true, that means we have tried to use this swapchain to recreate a new swapchain. The current
|
// If true, that means we have tried to use this swapchain to recreate a new swapchain. The
|
||||||
// swapchain can no longer be used for anything except presenting already-acquired images.
|
// 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 use a `Mutex` instead of an `AtomicBool` because we want to keep that locked while
|
||||||
// we acquire the image.
|
// we acquire the image.
|
||||||
@ -177,7 +178,6 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `create_info.usage` is empty.
|
/// - Panics if `create_info.usage` is empty.
|
||||||
#[inline]
|
|
||||||
pub fn recreate(
|
pub fn recreate(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
mut create_info: SwapchainCreateInfo,
|
mut create_info: SwapchainCreateInfo,
|
||||||
@ -726,7 +726,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the creation parameters of the swapchain.
|
/// Returns the creation parameters of the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn create_info(&self) -> SwapchainCreateInfo {
|
pub fn create_info(&self) -> SwapchainCreateInfo {
|
||||||
SwapchainCreateInfo {
|
SwapchainCreateInfo {
|
||||||
min_image_count: self.min_image_count,
|
min_image_count: self.min_image_count,
|
||||||
@ -747,37 +746,31 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the saved Surface, from the Swapchain creation.
|
/// Returns the saved Surface, from the Swapchain creation.
|
||||||
#[inline]
|
|
||||||
pub fn surface(&self) -> &Arc<Surface<W>> {
|
pub fn surface(&self) -> &Arc<Surface<W>> {
|
||||||
&self.surface
|
&self.surface
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the pre-transform that was passed when creating the swapchain.
|
/// Returns the pre-transform that was passed when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn pre_transform(&self) -> SurfaceTransform {
|
pub fn pre_transform(&self) -> SurfaceTransform {
|
||||||
self.pre_transform
|
self.pre_transform
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the alpha mode that was passed when creating the swapchain.
|
/// Returns the alpha mode that was passed when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn composite_alpha(&self) -> CompositeAlpha {
|
pub fn composite_alpha(&self) -> CompositeAlpha {
|
||||||
self.composite_alpha
|
self.composite_alpha
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the present mode that was passed when creating the swapchain.
|
/// Returns the present mode that was passed when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn present_mode(&self) -> PresentMode {
|
pub fn present_mode(&self) -> PresentMode {
|
||||||
self.present_mode
|
self.present_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of `clipped` that was passed when creating the swapchain.
|
/// Returns the value of `clipped` that was passed when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn clipped(&self) -> bool {
|
pub fn clipped(&self) -> bool {
|
||||||
self.clipped
|
self.clipped
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the value of 'full_screen_exclusive` that was passed when creating the swapchain.
|
/// Returns the value of 'full_screen_exclusive` that was passed when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn full_screen_exclusive(&self) -> FullScreenExclusive {
|
pub fn full_screen_exclusive(&self) -> FullScreenExclusive {
|
||||||
self.full_screen_exclusive
|
self.full_screen_exclusive
|
||||||
}
|
}
|
||||||
@ -875,7 +868,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Drop for Swapchain<W> {
|
impl<W> Drop for Swapchain<W> {
|
||||||
#[inline]
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let fns = self.device.fns();
|
let fns = self.device.fns();
|
||||||
@ -892,7 +884,6 @@ impl<W> Drop for Swapchain<W> {
|
|||||||
unsafe impl<W> VulkanObject for Swapchain<W> {
|
unsafe impl<W> VulkanObject for Swapchain<W> {
|
||||||
type Object = ash::vk::SwapchainKHR;
|
type Object = ash::vk::SwapchainKHR;
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn internal_object(&self) -> ash::vk::SwapchainKHR {
|
fn internal_object(&self) -> ash::vk::SwapchainKHR {
|
||||||
self.handle
|
self.handle
|
||||||
}
|
}
|
||||||
@ -905,7 +896,6 @@ unsafe impl<W> DeviceOwned for Swapchain<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W> PartialEq for Swapchain<W> {
|
impl<W> PartialEq for Swapchain<W> {
|
||||||
#[inline]
|
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.device() == other.device()
|
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> Eq for Swapchain<W> {}
|
||||||
|
|
||||||
impl<W> Hash for Swapchain<W> {
|
impl<W> Hash for Swapchain<W> {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -922,7 +911,6 @@ impl<W> Hash for Swapchain<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<W> Debug for Swapchain<W> {
|
impl<W> Debug for Swapchain<W> {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
let Self {
|
let Self {
|
||||||
handle,
|
handle,
|
||||||
@ -1005,7 +993,6 @@ unsafe impl<W> SwapchainAbstract for Swapchain<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn raw_image(&self, image_index: u32) -> Option<ImageInner<'_>> {
|
fn raw_image(&self, image_index: u32) -> Option<ImageInner<'_>> {
|
||||||
self.images.get(image_index as usize).map(|i| ImageInner {
|
self.images.get(image_index as usize).map(|i| ImageInner {
|
||||||
image: &i.image,
|
image: &i.image,
|
||||||
@ -1016,37 +1003,30 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image_count(&self) -> u32 {
|
fn image_count(&self) -> u32 {
|
||||||
self.images.len() as u32
|
self.images.len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image_format(&self) -> Format {
|
fn image_format(&self) -> Format {
|
||||||
self.image_format
|
self.image_format
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image_color_space(&self) -> ColorSpace {
|
fn image_color_space(&self) -> ColorSpace {
|
||||||
self.image_color_space
|
self.image_color_space
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image_extent(&self) -> [u32; 2] {
|
fn image_extent(&self) -> [u32; 2] {
|
||||||
self.image_extent
|
self.image_extent
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn image_array_layers(&self) -> u32 {
|
fn image_array_layers(&self) -> u32 {
|
||||||
self.image_array_layers
|
self.image_array_layers
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool {
|
unsafe fn full_screen_exclusive_held(&self) -> &AtomicBool {
|
||||||
&self.full_screen_exclusive_held
|
&self.full_screen_exclusive_held
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool {
|
unsafe fn try_claim_present_id(&self, present_id: NonZeroU64) -> bool {
|
||||||
let present_id = u64::from(present_id);
|
let present_id = u64::from(present_id);
|
||||||
self.prev_present_id.fetch_max(present_id, Ordering::SeqCst) < 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 Eq for dyn SwapchainAbstract {}
|
||||||
|
|
||||||
impl Hash for dyn SwapchainAbstract {
|
impl Hash for dyn SwapchainAbstract {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.internal_object().hash(state);
|
self.internal_object().hash(state);
|
||||||
self.device().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
|
/// The provided `image_array_layers` is greater than what is supported by the surface for this
|
||||||
/// device.
|
/// device.
|
||||||
ImageArrayLayersNotSupported {
|
ImageArrayLayersNotSupported { provided: u32, max_supported: u32 },
|
||||||
provided: u32,
|
|
||||||
max_supported: u32,
|
|
||||||
},
|
|
||||||
|
|
||||||
/// The provided `image_extent` is not within the range supported by the surface for this
|
/// The provided `image_extent` is not within the range supported by the surface for this
|
||||||
/// device.
|
/// device.
|
||||||
@ -1276,7 +1252,7 @@ pub enum SwapchainCreationError {
|
|||||||
supported: SupportedSurfaceTransforms,
|
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,
|
SurfaceNotSupported,
|
||||||
|
|
||||||
/// The swapchain has already been used to create a new one.
|
/// The swapchain has already been used to create a new one.
|
||||||
@ -1287,29 +1263,26 @@ pub enum SwapchainCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for SwapchainCreationError {
|
impl Error for SwapchainCreationError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for SwapchainCreationError {
|
impl Display for SwapchainCreationError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match self {
|
match self {
|
||||||
Self::OomError(_) => write!(f, "not enough memory available",),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
Self::DeviceLost => write!(f, "the device was lost",),
|
Self::DeviceLost => write!(f, "the device was lost"),
|
||||||
Self::SurfaceLost => write!(f, "the surface was lost",),
|
Self::SurfaceLost => write!(f, "the surface was lost"),
|
||||||
Self::SurfaceInUse => {
|
Self::SurfaceInUse => {
|
||||||
write!(f, "the surface is already used by another swapchain",)
|
write!(f, "the surface is already used by another swapchain")
|
||||||
}
|
}
|
||||||
Self::NativeWindowInUse => {
|
Self::NativeWindowInUse => {
|
||||||
write!(f, "the window is already in use by another API")
|
write!(f, "the window is already in use by another API")
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -1318,23 +1291,32 @@ impl Display for SwapchainCreationError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::CompositeAlphaNotSupported { .. } => write!(
|
Self::CompositeAlphaNotSupported { .. } => write!(
|
||||||
f,
|
f,
|
||||||
"the provided `composite_alpha` is not supported by the surface for this device",
|
"the provided `composite_alpha` is not supported by the surface for this device",
|
||||||
),
|
),
|
||||||
Self::FormatColorSpaceNotSupported => write!(
|
Self::FormatColorSpaceNotSupported => write!(
|
||||||
f,
|
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,
|
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,
|
provided, max_supported,
|
||||||
),
|
),
|
||||||
Self::ImageExtentNotSupported { provided, min_supported, max_supported } => write!(
|
Self::ImageExtentNotSupported {
|
||||||
|
provided,
|
||||||
|
min_supported,
|
||||||
|
max_supported,
|
||||||
|
} => write!(
|
||||||
f,
|
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,
|
provided, min_supported, max_supported,
|
||||||
),
|
),
|
||||||
Self::ImageExtentZeroLengthDimensions => write!(
|
Self::ImageExtentZeroLengthDimensions => write!(
|
||||||
@ -1343,20 +1325,31 @@ impl Display for SwapchainCreationError {
|
|||||||
),
|
),
|
||||||
Self::ImageFormatPropertiesNotSupported => write!(
|
Self::ImageFormatPropertiesNotSupported => write!(
|
||||||
f,
|
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,
|
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,
|
queue_family_index,
|
||||||
),
|
),
|
||||||
Self::ImageUsageNotSupported { .. } => write!(
|
Self::ImageUsageNotSupported { .. } => write!(
|
||||||
f,
|
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,
|
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,
|
provided, min_supported, max_supported,
|
||||||
),
|
),
|
||||||
Self::PresentModeNotSupported => write!(
|
Self::PresentModeNotSupported => write!(
|
||||||
@ -1371,10 +1364,9 @@ impl Display for SwapchainCreationError {
|
|||||||
f,
|
f,
|
||||||
"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",
|
||||||
),
|
),
|
||||||
Self::SwapchainAlreadyRetired => write!(
|
Self::SwapchainAlreadyRetired => {
|
||||||
f,
|
write!(f, "the swapchain has already been used to create a new one")
|
||||||
"the swapchain has already been used to create a new one",
|
}
|
||||||
),
|
|
||||||
Self::Win32MonitorInvalid => write!(
|
Self::Win32MonitorInvalid => write!(
|
||||||
f,
|
f,
|
||||||
"the `win32_monitor` value was `Some` when it must be `None` or vice-versa",
|
"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 {
|
impl From<VulkanError> for SwapchainCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> SwapchainCreationError {
|
fn from(err: VulkanError) -> SwapchainCreationError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
@ -1398,14 +1389,12 @@ impl From<VulkanError> for SwapchainCreationError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for SwapchainCreationError {
|
impl From<OomError> for SwapchainCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> SwapchainCreationError {
|
fn from(err: OomError) -> SwapchainCreationError {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for SwapchainCreationError {
|
impl From<RequirementNotMet> for SwapchainCreationError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -1449,7 +1438,6 @@ impl Win32Monitor {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// - `hmonitor` must be a valid handle as returned by the Win32 API.
|
/// - `hmonitor` must be a valid handle as returned by the Win32 API.
|
||||||
#[inline]
|
|
||||||
pub unsafe fn new<T>(hmonitor: *const T) -> Self {
|
pub unsafe fn new<T>(hmonitor: *const T) -> Self {
|
||||||
Self(hmonitor as _)
|
Self(hmonitor as _)
|
||||||
}
|
}
|
||||||
@ -1483,22 +1471,20 @@ pub enum FullScreenExclusiveError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for FullScreenExclusiveError {
|
impl Error for FullScreenExclusiveError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
FullScreenExclusiveError::OomError(ref err) => Some(err),
|
FullScreenExclusiveError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FullScreenExclusiveError {
|
impl Display for FullScreenExclusiveError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
FullScreenExclusiveError::OomError(_) => "not enough memory",
|
FullScreenExclusiveError::OomError(_) => "not enough memory",
|
||||||
FullScreenExclusiveError::SurfaceLost => {
|
FullScreenExclusiveError::SurfaceLost => {
|
||||||
"the surface of this swapchain is no longer valid"
|
"the surface of this swapchain is no longer valid"
|
||||||
@ -1519,7 +1505,6 @@ impl Display for FullScreenExclusiveError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for FullScreenExclusiveError {
|
impl From<VulkanError> for FullScreenExclusiveError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> FullScreenExclusiveError {
|
fn from(err: VulkanError) -> FullScreenExclusiveError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => {
|
err @ VulkanError::OutOfHostMemory => {
|
||||||
@ -1536,7 +1521,6 @@ impl From<VulkanError> for FullScreenExclusiveError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for FullScreenExclusiveError {
|
impl From<OomError> for FullScreenExclusiveError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> FullScreenExclusiveError {
|
fn from(err: OomError) -> FullScreenExclusiveError {
|
||||||
FullScreenExclusiveError::OomError(err)
|
FullScreenExclusiveError::OomError(err)
|
||||||
}
|
}
|
||||||
@ -1600,8 +1584,7 @@ pub fn acquire_next_image<W>(
|
|||||||
|
|
||||||
/// Presents an image on the screen.
|
/// Presents an image on the screen.
|
||||||
///
|
///
|
||||||
/// The actual behavior depends on the present mode that you passed when creating the
|
/// The actual behavior depends on the present mode that you passed when creating the swapchain.
|
||||||
/// swapchain.
|
|
||||||
pub fn present<F>(
|
pub fn present<F>(
|
||||||
before: F,
|
before: F,
|
||||||
queue: Arc<Queue>,
|
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
|
/// Returns a bool to represent if the presentation was suboptimal. In this case the swapchain is
|
||||||
/// usable, but the swapchain should be recreated as the Surface's properties no longer match the swapchain.
|
/// still usable, but the swapchain should be recreated as the Surface's properties no longer match
|
||||||
|
/// the swapchain.
|
||||||
pub fn wait_for_present<W>(
|
pub fn wait_for_present<W>(
|
||||||
swapchain: Arc<Swapchain<W>>,
|
swapchain: Arc<Swapchain<W>>,
|
||||||
present_id: u64,
|
present_id: u64,
|
||||||
@ -1704,13 +1689,11 @@ pub struct SwapchainAcquireFuture<W> {
|
|||||||
|
|
||||||
impl<W> SwapchainAcquireFuture<W> {
|
impl<W> SwapchainAcquireFuture<W> {
|
||||||
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn image_index(&self) -> u32 {
|
pub fn image_index(&self) -> u32 {
|
||||||
self.image_index
|
self.image_index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the corresponding swapchain.
|
/// Returns the corresponding swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
pub fn swapchain(&self) -> &Arc<Swapchain<W>> {
|
||||||
&self.swapchain
|
&self.swapchain
|
||||||
}
|
}
|
||||||
@ -1720,10 +1703,8 @@ unsafe impl<W> GpuFuture for SwapchainAcquireFuture<W>
|
|||||||
where
|
where
|
||||||
W: Send + Sync,
|
W: Send + Sync,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {}
|
fn cleanup_finished(&mut self) {}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
if let Some(ref semaphore) = self.semaphore {
|
if let Some(ref semaphore) = self.semaphore {
|
||||||
let sem = smallvec![semaphore.clone()];
|
let sem = smallvec![semaphore.clone()];
|
||||||
@ -1733,27 +1714,22 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
self.finished.store(true, Ordering::SeqCst);
|
self.finished.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
_buffer: &UnsafeBuffer,
|
_buffer: &UnsafeBuffer,
|
||||||
@ -1764,7 +1740,6 @@ where
|
|||||||
Err(AccessCheckError::Unknown)
|
Err(AccessCheckError::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -1833,7 +1808,6 @@ impl<W> Drop for SwapchainAcquireFuture<W> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<W> DeviceOwned for SwapchainAcquireFuture<W> {
|
unsafe impl<W> DeviceOwned for SwapchainAcquireFuture<W> {
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
&self.swapchain.device
|
&self.swapchain.device
|
||||||
}
|
}
|
||||||
@ -1871,22 +1845,20 @@ pub enum AcquireError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for AcquireError {
|
impl Error for AcquireError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
AcquireError::OomError(ref err) => Some(err),
|
AcquireError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for AcquireError {
|
impl Display for AcquireError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
AcquireError::OomError(_) => "not enough memory",
|
AcquireError::OomError(_) => "not enough memory",
|
||||||
AcquireError::DeviceLost => "the connection to the device has been lost",
|
AcquireError::DeviceLost => "the connection to the device has been lost",
|
||||||
AcquireError::Timeout => "no image is available for acquiring yet",
|
AcquireError::Timeout => "no image is available for acquiring yet",
|
||||||
@ -1915,14 +1887,12 @@ impl From<SemaphoreError> for AcquireError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for AcquireError {
|
impl From<OomError> for AcquireError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> AcquireError {
|
fn from(err: OomError) -> AcquireError {
|
||||||
AcquireError::OomError(err)
|
AcquireError::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for AcquireError {
|
impl From<VulkanError> for AcquireError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> AcquireError {
|
fn from(err: VulkanError) -> AcquireError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => AcquireError::OomError(OomError::from(err)),
|
||||||
@ -1970,19 +1940,17 @@ pub enum PresentWaitError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for PresentWaitError {
|
impl Error for PresentWaitError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for PresentWaitError {
|
impl Display for PresentWaitError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(e) => write!(f, "{}", e),
|
Self::OomError(e) => write!(f, "{}", e),
|
||||||
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
|
Self::DeviceLost => write!(f, "the connection to the device has been lost"),
|
||||||
Self::Timeout => write!(f, "no image is available for acquiring yet"),
|
Self::Timeout => write!(f, "no image is available for acquiring yet"),
|
||||||
@ -2005,14 +1973,12 @@ impl Display for PresentWaitError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for PresentWaitError {
|
impl From<OomError> for PresentWaitError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> PresentWaitError {
|
fn from(err: OomError) -> PresentWaitError {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for PresentWaitError {
|
impl From<RequirementNotMet> for PresentWaitError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
@ -2022,7 +1988,6 @@ impl From<RequirementNotMet> for PresentWaitError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for PresentWaitError {
|
impl From<VulkanError> for PresentWaitError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> PresentWaitError {
|
fn from(err: VulkanError) -> PresentWaitError {
|
||||||
match err {
|
match err {
|
||||||
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
err @ VulkanError::OutOfHostMemory => Self::OomError(OomError::from(err)),
|
||||||
@ -2058,13 +2023,11 @@ where
|
|||||||
P: GpuFuture,
|
P: GpuFuture,
|
||||||
{
|
{
|
||||||
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
/// Returns the index of the image in the list of images returned when creating the swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn image_id(&self) -> u32 {
|
pub fn image_id(&self) -> u32 {
|
||||||
self.swapchain_info.image_index
|
self.swapchain_info.image_index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the corresponding swapchain.
|
/// Returns the corresponding swapchain.
|
||||||
#[inline]
|
|
||||||
pub fn swapchain(&self) -> &Arc<dyn SwapchainAbstract> {
|
pub fn swapchain(&self) -> &Arc<dyn SwapchainAbstract> {
|
||||||
&self.swapchain_info.swapchain
|
&self.swapchain_info.swapchain
|
||||||
}
|
}
|
||||||
@ -2074,12 +2037,10 @@ unsafe impl<P> GpuFuture for PresentFuture<P>
|
|||||||
where
|
where
|
||||||
P: GpuFuture,
|
P: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.previous.cleanup_finished();
|
self.previous.cleanup_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
if self.flushed.load(Ordering::SeqCst) {
|
if self.flushed.load(Ordering::SeqCst) {
|
||||||
return Ok(SubmitAnyBuilder::Empty);
|
return Ok(SubmitAnyBuilder::Empty);
|
||||||
@ -2148,7 +2109,6 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
// If `flushed` already contains `true`, then `build_submission` will return `Empty`.
|
// If `flushed` already contains `true`, then `build_submission` will return `Empty`.
|
||||||
@ -2194,19 +2154,16 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
self.flushed.store(true, Ordering::SeqCst);
|
self.flushed.store(true, Ordering::SeqCst);
|
||||||
self.finished.store(true, Ordering::SeqCst);
|
self.finished.store(true, Ordering::SeqCst);
|
||||||
self.previous.signal_finished();
|
self.previous.signal_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
debug_assert!(match self.previous.queue() {
|
debug_assert!(match self.previous.queue() {
|
||||||
None => true,
|
None => true,
|
||||||
@ -2216,7 +2173,6 @@ where
|
|||||||
Some(self.queue.clone())
|
Some(self.queue.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -2228,7 +2184,6 @@ where
|
|||||||
.check_buffer_access(buffer, range, exclusive, queue)
|
.check_buffer_access(buffer, range, exclusive, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -2281,7 +2236,6 @@ unsafe impl<P> DeviceOwned for PresentFuture<P>
|
|||||||
where
|
where
|
||||||
P: GpuFuture,
|
P: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.queue.device()
|
self.queue.device()
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ pub struct Event {
|
|||||||
|
|
||||||
impl Event {
|
impl Event {
|
||||||
/// Creates a new `Event`.
|
/// Creates a new `Event`.
|
||||||
|
#[inline]
|
||||||
pub fn new(device: Arc<Device>, _create_info: EventCreateInfo) -> Result<Event, OomError> {
|
pub fn new(device: Arc<Device>, _create_info: EventCreateInfo) -> Result<Event, OomError> {
|
||||||
let create_info = ash::vk::EventCreateInfo {
|
let create_info = ash::vk::EventCreateInfo {
|
||||||
flags: ash::vk::EventCreateFlags::empty(),
|
flags: ash::vk::EventCreateFlags::empty(),
|
||||||
@ -66,6 +67,7 @@ impl Event {
|
|||||||
///
|
///
|
||||||
/// For most applications, using the event pool should be preferred,
|
/// For most applications, using the event pool should be preferred,
|
||||||
/// in order to avoid creating new events every frame.
|
/// in order to avoid creating new events every frame.
|
||||||
|
#[inline]
|
||||||
pub fn from_pool(device: Arc<Device>) -> Result<Event, OomError> {
|
pub fn from_pool(device: Arc<Device>) -> Result<Event, OomError> {
|
||||||
let handle = device.event_pool().lock().pop();
|
let handle = device.event_pool().lock().pop();
|
||||||
let event = match handle {
|
let event = match handle {
|
||||||
@ -100,6 +102,7 @@ impl Event {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::Event,
|
handle: ash::vk::Event,
|
||||||
@ -142,10 +145,9 @@ impl Event {
|
|||||||
///
|
///
|
||||||
/// If a command buffer is waiting on this event, it is then unblocked.
|
/// 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.
|
/// - Panics if the device or host ran out of memory.
|
||||||
///
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set(&mut self) {
|
pub fn set(&mut self) {
|
||||||
self.set_raw().unwrap();
|
self.set_raw().unwrap();
|
||||||
@ -165,10 +167,9 @@ impl Event {
|
|||||||
|
|
||||||
/// Changes the `Event` to the unsignaled state.
|
/// Changes the `Event` to the unsignaled state.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if the device or host ran out of memory.
|
/// - Panics if the device or host ran out of memory.
|
||||||
///
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn reset(&mut self) {
|
pub fn reset(&mut self) {
|
||||||
self.reset_raw().unwrap();
|
self.reset_raw().unwrap();
|
||||||
@ -216,7 +217,6 @@ impl PartialEq for Event {
|
|||||||
impl Eq for Event {}
|
impl Eq for Event {}
|
||||||
|
|
||||||
impl Hash for Event {
|
impl Hash for Event {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -230,6 +230,7 @@ pub struct EventCreateInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EventCreateInfo {
|
impl Default for EventCreateInfo {
|
||||||
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
|
@ -103,6 +103,7 @@ impl Fence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn new_unchecked(
|
pub unsafe fn new_unchecked(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
create_info: FenceCreateInfo,
|
create_info: FenceCreateInfo,
|
||||||
@ -148,6 +149,7 @@ impl Fence {
|
|||||||
)
|
)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
output.assume_init()
|
output.assume_init()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -171,6 +173,7 @@ impl Fence {
|
|||||||
///
|
///
|
||||||
/// For most applications, using the fence pool should be preferred,
|
/// For most applications, using the fence pool should be preferred,
|
||||||
/// in order to avoid creating new fences every frame.
|
/// in order to avoid creating new fences every frame.
|
||||||
|
#[inline]
|
||||||
pub fn from_pool(device: Arc<Device>) -> Result<Fence, FenceError> {
|
pub fn from_pool(device: Arc<Device>) -> Result<Fence, FenceError> {
|
||||||
let handle = device.fence_pool().lock().pop();
|
let handle = device.fence_pool().lock().pop();
|
||||||
let fence = match handle {
|
let fence = match handle {
|
||||||
@ -210,6 +213,7 @@ impl Fence {
|
|||||||
///
|
///
|
||||||
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
/// - `handle` must be a valid Vulkan object handle created from `device`.
|
||||||
/// - `create_info` must match the info used to create the object.
|
/// - `create_info` must match the info used to create the object.
|
||||||
|
#[inline]
|
||||||
pub unsafe fn from_handle(
|
pub unsafe fn from_handle(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
handle: ash::vk::Fence,
|
handle: ash::vk::Fence,
|
||||||
@ -236,6 +240,7 @@ impl Fence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the fence is signaled.
|
/// Returns true if the fence is signaled.
|
||||||
|
#[inline]
|
||||||
pub fn is_signaled(&self) -> Result<bool, OomError> {
|
pub fn is_signaled(&self) -> Result<bool, OomError> {
|
||||||
let queue_to_signal = {
|
let queue_to_signal = {
|
||||||
let mut state = self.lock();
|
let mut state = self.lock();
|
||||||
@ -322,10 +327,9 @@ impl Fence {
|
|||||||
|
|
||||||
/// Waits for multiple fences at once.
|
/// Waits for multiple fences at once.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// Panics if not all fences belong to the same device.
|
/// - Panics if not all fences belong to the same device.
|
||||||
#[inline]
|
|
||||||
pub fn multi_wait<'a>(
|
pub fn multi_wait<'a>(
|
||||||
fences: impl IntoIterator<Item = &'a Fence>,
|
fences: impl IntoIterator<Item = &'a Fence>,
|
||||||
timeout: Option<Duration>,
|
timeout: Option<Duration>,
|
||||||
@ -442,8 +446,10 @@ impl Fence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
|
#[inline]
|
||||||
pub unsafe fn reset_unchecked(&self) -> Result<(), VulkanError> {
|
pub unsafe fn reset_unchecked(&self) -> Result<(), VulkanError> {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
|
|
||||||
self.reset_unchecked_locked(&mut state)
|
self.reset_unchecked_locked(&mut state)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,10 +468,9 @@ impl Fence {
|
|||||||
///
|
///
|
||||||
/// The fences must not be in use by a queue operation.
|
/// The fences must not be in use by a queue operation.
|
||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if not all fences belong to the same device.
|
/// - Panics if not all fences belong to the same device.
|
||||||
#[inline]
|
|
||||||
pub fn multi_reset<'a>(fences: impl IntoIterator<Item = &'a Fence>) -> Result<(), FenceError> {
|
pub fn multi_reset<'a>(fences: impl IntoIterator<Item = &'a Fence>) -> Result<(), FenceError> {
|
||||||
let (fences, mut states): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = fences
|
let (fences, mut states): (SmallVec<[_; 8]>, SmallVec<[_; 8]>) = fences
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -503,7 +508,6 @@ impl Fence {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
#[cfg_attr(not(feature = "document_unchecked"), doc(hidden))]
|
||||||
#[inline]
|
|
||||||
pub unsafe fn multi_reset_unchecked<'a>(
|
pub unsafe fn multi_reset_unchecked<'a>(
|
||||||
fences: impl IntoIterator<Item = &'a Fence>,
|
fences: impl IntoIterator<Item = &'a Fence>,
|
||||||
) -> Result<(), VulkanError> {
|
) -> Result<(), VulkanError> {
|
||||||
@ -514,6 +518,7 @@ impl Fence {
|
|||||||
(fence, state)
|
(fence, state)
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
Self::multi_reset_unchecked_locked(&fences, &mut states)
|
Self::multi_reset_unchecked_locked(&fences, &mut states)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +549,6 @@ impl Fence {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn lock(&self) -> MutexGuard<'_, FenceState> {
|
pub(crate) fn lock(&self) -> MutexGuard<'_, FenceState> {
|
||||||
self.state.lock()
|
self.state.lock()
|
||||||
}
|
}
|
||||||
@ -591,7 +595,6 @@ impl PartialEq for Fence {
|
|||||||
impl Eq for Fence {}
|
impl Eq for Fence {}
|
||||||
|
|
||||||
impl Hash for Fence {
|
impl Hash for Fence {
|
||||||
#[inline]
|
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.device().hash(state);
|
self.device().hash(state);
|
||||||
@ -607,17 +610,14 @@ pub struct FenceState {
|
|||||||
impl FenceState {
|
impl FenceState {
|
||||||
/// If the fence is already signaled, or it's unsignaled but there's no queue that
|
/// If the fence is already signaled, or it's unsignaled but there's no queue that
|
||||||
/// could signal it, returns the currently known value.
|
/// could signal it, returns the currently known value.
|
||||||
#[inline]
|
|
||||||
pub(crate) fn status(&self) -> Option<bool> {
|
pub(crate) fn status(&self) -> Option<bool> {
|
||||||
(self.is_signaled || self.in_use_by.is_none()).then_some(self.is_signaled)
|
(self.is_signaled || self.in_use_by.is_none()).then_some(self.is_signaled)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) fn is_in_use(&self) -> bool {
|
pub(crate) fn is_in_use(&self) -> bool {
|
||||||
self.in_use_by.is_some()
|
self.in_use_by.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) unsafe fn add_to_queue(&mut self, queue: &Arc<Queue>) {
|
pub(crate) unsafe fn add_to_queue(&mut self, queue: &Arc<Queue>) {
|
||||||
self.is_signaled = false;
|
self.is_signaled = false;
|
||||||
self.in_use_by = Some(Arc::downgrade(queue));
|
self.in_use_by = Some(Arc::downgrade(queue));
|
||||||
@ -625,20 +625,17 @@ impl FenceState {
|
|||||||
|
|
||||||
/// Called when a fence first discovers that it is signaled.
|
/// Called when a fence first discovers that it is signaled.
|
||||||
/// Returns the queue that should be informed about it.
|
/// Returns the queue that should be informed about it.
|
||||||
#[inline]
|
|
||||||
pub(crate) unsafe fn set_signaled(&mut self) -> Option<Arc<Queue>> {
|
pub(crate) unsafe fn set_signaled(&mut self) -> Option<Arc<Queue>> {
|
||||||
self.is_signaled = true;
|
self.is_signaled = true;
|
||||||
self.in_use_by.take().and_then(|queue| queue.upgrade())
|
self.in_use_by.take().and_then(|queue| queue.upgrade())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called when a queue is unlocking resources.
|
/// Called when a queue is unlocking resources.
|
||||||
#[inline]
|
|
||||||
pub(crate) unsafe fn set_finished(&mut self) {
|
pub(crate) unsafe fn set_finished(&mut self) {
|
||||||
self.is_signaled = true;
|
self.is_signaled = true;
|
||||||
self.in_use_by = None;
|
self.in_use_by = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub(crate) unsafe fn reset(&mut self) {
|
pub(crate) unsafe fn reset(&mut self) {
|
||||||
debug_assert!(self.in_use_by.is_none());
|
debug_assert!(self.in_use_by.is_none());
|
||||||
self.is_signaled = false;
|
self.is_signaled = false;
|
||||||
@ -795,10 +792,9 @@ pub enum FenceError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for FenceError {
|
impl Error for FenceError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
Self::OomError(ref err) => Some(err),
|
Self::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,7 +806,6 @@ impl Display for FenceError {
|
|||||||
Self::OomError(_) => write!(f, "not enough memory available"),
|
Self::OomError(_) => write!(f, "not enough memory available"),
|
||||||
Self::DeviceLost => write!(f, "the device was lost"),
|
Self::DeviceLost => write!(f, "the device was lost"),
|
||||||
Self::Timeout => write!(f, "the timeout has been reached"),
|
Self::Timeout => write!(f, "the timeout has been reached"),
|
||||||
|
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for,
|
required_for,
|
||||||
requires_one_of,
|
requires_one_of,
|
||||||
@ -819,14 +814,12 @@ impl Display for FenceError {
|
|||||||
"a requirement was not met for: {}; requires one of: {}",
|
"a requirement was not met for: {}; requires one of: {}",
|
||||||
required_for, requires_one_of,
|
required_for, requires_one_of,
|
||||||
),
|
),
|
||||||
|
|
||||||
Self::InUse => write!(f, "the fence is currently in use by a queue"),
|
Self::InUse => write!(f, "the fence is currently in use by a queue"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for FenceError {
|
impl From<VulkanError> for FenceError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
e @ VulkanError::OutOfHostMemory | e @ VulkanError::OutOfDeviceMemory => {
|
||||||
@ -839,14 +832,12 @@ impl From<VulkanError> for FenceError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<OomError> for FenceError {
|
impl From<OomError> for FenceError {
|
||||||
#[inline]
|
|
||||||
fn from(err: OomError) -> Self {
|
fn from(err: OomError) -> Self {
|
||||||
Self::OomError(err)
|
Self::OomError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<RequirementNotMet> for FenceError {
|
impl From<RequirementNotMet> for FenceError {
|
||||||
#[inline]
|
|
||||||
fn from(err: RequirementNotMet) -> Self {
|
fn from(err: RequirementNotMet) -> Self {
|
||||||
Self::RequirementNotMet {
|
Self::RequirementNotMet {
|
||||||
required_for: err.required_for,
|
required_for: err.required_for,
|
||||||
|
@ -20,7 +20,6 @@ use parking_lot::{Mutex, MutexGuard};
|
|||||||
use std::{mem::replace, ops::Range, sync::Arc, time::Duration};
|
use std::{mem::replace, ops::Range, sync::Arc, time::Duration};
|
||||||
|
|
||||||
/// Builds a new fence signal future.
|
/// Builds a new fence signal future.
|
||||||
#[inline]
|
|
||||||
pub fn then_signal_fence<F>(future: F, behavior: FenceSignalFutureBehavior) -> FenceSignalFuture<F>
|
pub fn then_signal_fence<F>(future: F, behavior: FenceSignalFutureBehavior) -> FenceSignalFuture<F>
|
||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
@ -167,7 +166,6 @@ where
|
|||||||
{
|
{
|
||||||
// Implementation of `cleanup_finished`, but takes a `&self` instead of a `&mut self`.
|
// 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>`.
|
// This is an external function so that we can also call it from an `Arc<FenceSignalFuture>`.
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished_impl(&self) {
|
fn cleanup_finished_impl(&self) {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
|
|
||||||
@ -353,12 +351,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<F> FenceSignalFutureState<F> {
|
impl<F> FenceSignalFutureState<F> {
|
||||||
#[inline]
|
|
||||||
fn get_prev(&self) -> Option<&F> {
|
fn get_prev(&self) -> Option<&F> {
|
||||||
match *self {
|
match self {
|
||||||
FenceSignalFutureState::Pending(ref prev, _) => Some(prev),
|
FenceSignalFutureState::Pending(prev, _) => Some(prev),
|
||||||
FenceSignalFutureState::PartiallyFlushed(ref prev, _) => Some(prev),
|
FenceSignalFutureState::PartiallyFlushed(prev, _) => Some(prev),
|
||||||
FenceSignalFutureState::Flushed(ref prev, _) => Some(prev),
|
FenceSignalFutureState::Flushed(prev, _) => Some(prev),
|
||||||
FenceSignalFutureState::Cleaned => None,
|
FenceSignalFutureState::Cleaned => None,
|
||||||
FenceSignalFutureState::Poisoned => None,
|
FenceSignalFutureState::Poisoned => None,
|
||||||
}
|
}
|
||||||
@ -369,18 +366,16 @@ unsafe impl<F> GpuFuture for FenceSignalFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.cleanup_finished_impl()
|
self.cleanup_finished_impl()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
self.flush_impl(&mut state)?;
|
self.flush_impl(&mut state)?;
|
||||||
|
|
||||||
match *state {
|
match &*state {
|
||||||
FenceSignalFutureState::Flushed(_, ref fence) => match self.behavior {
|
FenceSignalFutureState::Flushed(_, fence) => match self.behavior {
|
||||||
FenceSignalFutureBehavior::Block { timeout } => {
|
FenceSignalFutureBehavior::Block { timeout } => {
|
||||||
fence.wait(timeout)?;
|
fence.wait(timeout)?;
|
||||||
}
|
}
|
||||||
@ -394,13 +389,11 @@ where
|
|||||||
Ok(SubmitAnyBuilder::Empty)
|
Ok(SubmitAnyBuilder::Empty)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
let mut state = self.state.lock();
|
let mut state = self.state.lock();
|
||||||
self.flush_impl(&mut state)
|
self.flush_impl(&mut state)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
let state = self.state.lock();
|
let state = self.state.lock();
|
||||||
match *state {
|
match *state {
|
||||||
@ -412,7 +405,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
match self.behavior {
|
match self.behavior {
|
||||||
FenceSignalFutureBehavior::Continue => {
|
FenceSignalFutureBehavior::Continue => {
|
||||||
@ -423,7 +415,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
let state = self.state.lock();
|
let state = self.state.lock();
|
||||||
if let Some(prev) = state.get_prev() {
|
if let Some(prev) = state.get_prev() {
|
||||||
@ -433,7 +424,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -449,7 +439,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -484,7 +473,6 @@ unsafe impl<F> DeviceOwned for FenceSignalFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
@ -528,39 +516,32 @@ unsafe impl<F> GpuFuture for Arc<FenceSignalFuture<F>>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.cleanup_finished_impl()
|
self.cleanup_finished_impl()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
// Note that this is sound because we always return `SubmitAnyBuilder::Empty`. See the
|
// Note that this is sound because we always return `SubmitAnyBuilder::Empty`. See the
|
||||||
// documentation of `build_submission`.
|
// documentation of `build_submission`.
|
||||||
(**self).build_submission()
|
(**self).build_submission()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
(**self).flush()
|
(**self).flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
(**self).signal_finished()
|
(**self).signal_finished()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
(**self).queue_change_allowed()
|
(**self).queue_change_allowed()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
(**self).queue()
|
(**self).queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -571,7 +552,6 @@ where
|
|||||||
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
|
@ -19,7 +19,6 @@ use std::{ops::Range, sync::Arc};
|
|||||||
|
|
||||||
/// Joins two futures together.
|
/// Joins two futures together.
|
||||||
// TODO: handle errors
|
// TODO: handle errors
|
||||||
#[inline]
|
|
||||||
pub fn join<F, S>(first: F, second: S) -> JoinFuture<F, S>
|
pub fn join<F, S>(first: F, second: S) -> JoinFuture<F, S>
|
||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
@ -49,7 +48,6 @@ where
|
|||||||
A: DeviceOwned,
|
A: DeviceOwned,
|
||||||
B: DeviceOwned,
|
B: DeviceOwned,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
let device = self.first.device();
|
let device = self.first.device();
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
@ -65,22 +63,20 @@ where
|
|||||||
A: GpuFuture,
|
A: GpuFuture,
|
||||||
B: GpuFuture,
|
B: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.first.cleanup_finished();
|
self.first.cleanup_finished();
|
||||||
self.second.cleanup_finished();
|
self.second.cleanup_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
// Since each future remembers whether it has been flushed, there's no safety issue here
|
// Since each future remembers whether it has been flushed, there's no safety issue here
|
||||||
// if we call this function multiple times.
|
// if we call this function multiple times.
|
||||||
self.first.flush()?;
|
self.first.flush()?;
|
||||||
self.second.flush()?;
|
self.second.flush()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
// TODO: review this function
|
// TODO: review this function
|
||||||
let first = self.first.build_submission()?;
|
let first = self.first.build_submission()?;
|
||||||
@ -179,18 +175,15 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
self.first.signal_finished();
|
self.first.signal_finished();
|
||||||
self.second.signal_finished();
|
self.second.signal_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
self.first.queue_change_allowed() && self.second.queue_change_allowed()
|
self.first.queue_change_allowed() && self.second.queue_change_allowed()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
match (self.first.queue(), self.second.queue()) {
|
match (self.first.queue(), self.second.queue()) {
|
||||||
(Some(q1), Some(q2)) => {
|
(Some(q1), Some(q2)) => {
|
||||||
@ -210,7 +203,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -245,7 +237,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
|
@ -145,7 +145,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
/// Checks whether accessing a swapchain image is permitted.
|
/// Checks whether accessing a swapchain image is permitted.
|
||||||
///
|
///
|
||||||
/// > **Note**: Setting `before` to `true` should skip checking the current future and always
|
/// > **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(
|
fn check_swapchain_image_acquired(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -166,7 +166,6 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
///
|
///
|
||||||
/// > **Note**: This is just a shortcut function. The actual implementation is in the
|
/// > **Note**: This is just a shortcut function. The actual implementation is in the
|
||||||
/// > `CommandBuffer` trait.
|
/// > `CommandBuffer` trait.
|
||||||
#[inline]
|
|
||||||
fn then_execute<Cb>(
|
fn then_execute<Cb>(
|
||||||
self,
|
self,
|
||||||
queue: Arc<Queue>,
|
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
|
/// > **Note**: This is just a shortcut function. The actual implementation is in the
|
||||||
/// > `CommandBuffer` trait.
|
/// > `CommandBuffer` trait.
|
||||||
#[inline]
|
|
||||||
fn then_execute_same_queue<Cb>(
|
fn then_execute_same_queue<Cb>(
|
||||||
self,
|
self,
|
||||||
command_buffer: Cb,
|
command_buffer: Cb,
|
||||||
@ -228,6 +226,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
{
|
{
|
||||||
let f = self.then_signal_semaphore();
|
let f = self.then_signal_semaphore();
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
|
|
||||||
Ok(f)
|
Ok(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,6 +252,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
{
|
{
|
||||||
let f = self.then_signal_fence();
|
let f = self.then_signal_fence();
|
||||||
f.flush()?;
|
f.flush()?;
|
||||||
|
|
||||||
Ok(f)
|
Ok(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +277,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
/// Turn the current future into a `Box<dyn GpuFuture>`.
|
/// Turn the current future into a `Box<dyn GpuFuture>`.
|
||||||
///
|
///
|
||||||
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture>`.
|
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture>`.
|
||||||
|
#[inline]
|
||||||
fn boxed(self) -> Box<dyn GpuFuture>
|
fn boxed(self) -> Box<dyn GpuFuture>
|
||||||
where
|
where
|
||||||
Self: Sized + 'static,
|
Self: Sized + 'static,
|
||||||
@ -287,6 +288,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
/// Turn the current future into a `Box<dyn GpuFuture + Send>`.
|
/// 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>`.
|
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Send>`.
|
||||||
|
#[inline]
|
||||||
fn boxed_send(self) -> Box<dyn GpuFuture + Send>
|
fn boxed_send(self) -> Box<dyn GpuFuture + Send>
|
||||||
where
|
where
|
||||||
Self: Sized + Send + 'static,
|
Self: Sized + Send + 'static,
|
||||||
@ -297,6 +299,7 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
/// Turn the current future into a `Box<dyn GpuFuture + Sync>`.
|
/// 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>`.
|
/// This is a helper function that calls `Box::new(yourFuture) as Box<dyn GpuFuture + Sync>`.
|
||||||
|
#[inline]
|
||||||
fn boxed_sync(self) -> Box<dyn GpuFuture + Sync>
|
fn boxed_sync(self) -> Box<dyn GpuFuture + Sync>
|
||||||
where
|
where
|
||||||
Self: Sized + Sync + 'static,
|
Self: Sized + Sync + 'static,
|
||||||
@ -306,7 +309,9 @@ pub unsafe trait GpuFuture: DeviceOwned {
|
|||||||
|
|
||||||
/// Turn the current future into a `Box<dyn GpuFuture + Send + Sync>`.
|
/// 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>
|
fn boxed_send_sync(self) -> Box<dyn GpuFuture + Send + Sync>
|
||||||
where
|
where
|
||||||
Self: Sized + Send + Sync + 'static,
|
Self: Sized + Send + Sync + 'static,
|
||||||
@ -319,37 +324,30 @@ unsafe impl<F: ?Sized> GpuFuture for Box<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
(**self).cleanup_finished()
|
(**self).cleanup_finished()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
(**self).build_submission()
|
(**self).build_submission()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn flush(&self) -> Result<(), FlushError> {
|
fn flush(&self) -> Result<(), FlushError> {
|
||||||
(**self).flush()
|
(**self).flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
(**self).signal_finished()
|
(**self).signal_finished()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
(**self).queue_change_allowed()
|
(**self).queue_change_allowed()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
(**self).queue()
|
(**self).queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -360,7 +358,6 @@ where
|
|||||||
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
(**self).check_buffer_access(buffer, range, exclusive, queue)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -431,12 +428,11 @@ pub enum AccessError {
|
|||||||
impl Error for AccessError {}
|
impl Error for AccessError {}
|
||||||
|
|
||||||
impl Display for AccessError {
|
impl Display for AccessError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
AccessError::ExclusiveDenied => "only shared access is allowed for this resource",
|
AccessError::ExclusiveDenied => "only shared access is allowed for this resource",
|
||||||
AccessError::AlreadyInUse => {
|
AccessError::AlreadyInUse => {
|
||||||
"the resource is already in use, and there is no tracking of concurrent usages"
|
"the resource is already in use, and there is no tracking of concurrent usages"
|
||||||
@ -446,14 +442,14 @@ impl Display for AccessError {
|
|||||||
}
|
}
|
||||||
AccessError::ImageNotInitialized { .. } => {
|
AccessError::ImageNotInitialized { .. } => {
|
||||||
"trying to use an image without transitioning it from the undefined or \
|
"trying to use an image without transitioning it from the undefined or \
|
||||||
preinitialized layouts first"
|
preinitialized layouts first"
|
||||||
}
|
}
|
||||||
AccessError::BufferNotInitialized => {
|
AccessError::BufferNotInitialized => {
|
||||||
"trying to use a buffer that still contains garbage data"
|
"trying to use a buffer that still contains garbage data"
|
||||||
}
|
}
|
||||||
AccessError::SwapchainImageNotAcquired => {
|
AccessError::SwapchainImageNotAcquired => {
|
||||||
"trying to use a swapchain image without depending on a corresponding acquire \
|
"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 Error for AccessCheckError {}
|
||||||
|
|
||||||
impl Display for AccessCheckError {
|
impl Display for AccessCheckError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
AccessCheckError::Denied(_) => "access to the resource has been denied",
|
AccessCheckError::Denied(_) => "access to the resource has been denied",
|
||||||
AccessCheckError::Unknown => "the resource is unknown",
|
AccessCheckError::Unknown => "the resource is unknown",
|
||||||
}
|
}
|
||||||
@ -486,7 +481,6 @@ impl Display for AccessCheckError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<AccessError> for AccessCheckError {
|
impl From<AccessError> for AccessCheckError {
|
||||||
#[inline]
|
|
||||||
fn from(err: AccessError) -> AccessCheckError {
|
fn from(err: AccessError) -> AccessCheckError {
|
||||||
AccessCheckError::Denied(err)
|
AccessCheckError::Denied(err)
|
||||||
}
|
}
|
||||||
@ -524,23 +518,21 @@ pub enum FlushError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Error for FlushError {
|
impl Error for FlushError {
|
||||||
#[inline]
|
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match *self {
|
match self {
|
||||||
FlushError::AccessError(ref err) => Some(err),
|
FlushError::AccessError(err) => Some(err),
|
||||||
FlushError::OomError(ref err) => Some(err),
|
FlushError::OomError(err) => Some(err),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for FlushError {
|
impl Display for FlushError {
|
||||||
#[inline]
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), FmtError> {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"{}",
|
"{}",
|
||||||
match *self {
|
match self {
|
||||||
FlushError::AccessError(_) => "access to a resource has been denied",
|
FlushError::AccessError(_) => "access to a resource has been denied",
|
||||||
FlushError::OomError(_) => "not enough memory",
|
FlushError::OomError(_) => "not enough memory",
|
||||||
FlushError::DeviceLost => "the connection to the device has been lost",
|
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"
|
"the swapchain no longer has full screen exclusivity"
|
||||||
}
|
}
|
||||||
FlushError::Timeout => {
|
FlushError::Timeout => {
|
||||||
"the flush operation needed to block, but the timeout has \
|
"the flush operation needed to block, but the timeout has elapsed"
|
||||||
elapsed"
|
|
||||||
}
|
}
|
||||||
FlushError::PresentIdLessThanOrEqual => {
|
FlushError::PresentIdLessThanOrEqual => {
|
||||||
"present id is less than or equal to previous"
|
"present id is less than or equal to previous"
|
||||||
@ -562,14 +553,12 @@ impl Display for FlushError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<AccessError> for FlushError {
|
impl From<AccessError> for FlushError {
|
||||||
#[inline]
|
|
||||||
fn from(err: AccessError) -> FlushError {
|
fn from(err: AccessError) -> FlushError {
|
||||||
FlushError::AccessError(err)
|
FlushError::AccessError(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<VulkanError> for FlushError {
|
impl From<VulkanError> for FlushError {
|
||||||
#[inline]
|
|
||||||
fn from(err: VulkanError) -> Self {
|
fn from(err: VulkanError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
VulkanError::OutOfHostMemory | VulkanError::OutOfDeviceMemory => {
|
||||||
@ -585,7 +574,6 @@ impl From<VulkanError> for FlushError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<FenceError> for FlushError {
|
impl From<FenceError> for FlushError {
|
||||||
#[inline]
|
|
||||||
fn from(err: FenceError) -> FlushError {
|
fn from(err: FenceError) -> FlushError {
|
||||||
match err {
|
match err {
|
||||||
FenceError::OomError(err) => FlushError::OomError(err),
|
FenceError::OomError(err) => FlushError::OomError(err),
|
||||||
|
@ -27,7 +27,6 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Builds a new semaphore signal future.
|
/// Builds a new semaphore signal future.
|
||||||
#[inline]
|
|
||||||
pub fn then_signal_semaphore<F>(future: F) -> SemaphoreSignalFuture<F>
|
pub fn then_signal_semaphore<F>(future: F) -> SemaphoreSignalFuture<F>
|
||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
@ -64,17 +63,15 @@ unsafe impl<F> GpuFuture for SemaphoreSignalFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn cleanup_finished(&mut self) {
|
fn cleanup_finished(&mut self) {
|
||||||
self.previous.cleanup_finished();
|
self.previous.cleanup_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
unsafe fn build_submission(&self) -> Result<SubmitAnyBuilder, FlushError> {
|
||||||
// Flushing the signaling part, since it must always be submitted before the waiting part.
|
// Flushing the signaling part, since it must always be submitted before the waiting part.
|
||||||
self.flush()?;
|
self.flush()?;
|
||||||
|
|
||||||
let sem = smallvec![self.semaphore.clone()];
|
let sem = smallvec![self.semaphore.clone()];
|
||||||
|
|
||||||
Ok(SubmitAnyBuilder::SemaphoresWait(sem))
|
Ok(SubmitAnyBuilder::SemaphoresWait(sem))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,24 +190,20 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
unsafe fn signal_finished(&self) {
|
unsafe fn signal_finished(&self) {
|
||||||
debug_assert!(*self.wait_submitted.lock());
|
debug_assert!(*self.wait_submitted.lock());
|
||||||
self.finished.store(true, Ordering::SeqCst);
|
self.finished.store(true, Ordering::SeqCst);
|
||||||
self.previous.signal_finished();
|
self.previous.signal_finished();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue_change_allowed(&self) -> bool {
|
fn queue_change_allowed(&self) -> bool {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn queue(&self) -> Option<Arc<Queue>> {
|
fn queue(&self) -> Option<Arc<Queue>> {
|
||||||
self.previous.queue()
|
self.previous.queue()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_buffer_access(
|
fn check_buffer_access(
|
||||||
&self,
|
&self,
|
||||||
buffer: &UnsafeBuffer,
|
buffer: &UnsafeBuffer,
|
||||||
@ -223,7 +216,6 @@ where
|
|||||||
.map(|_| None)
|
.map(|_| None)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn check_image_access(
|
fn check_image_access(
|
||||||
&self,
|
&self,
|
||||||
image: &UnsafeImage,
|
image: &UnsafeImage,
|
||||||
@ -251,7 +243,6 @@ unsafe impl<F> DeviceOwned for SemaphoreSignalFuture<F>
|
|||||||
where
|
where
|
||||||
F: GpuFuture,
|
F: GpuFuture,
|
||||||
{
|
{
|
||||||
#[inline]
|
|
||||||
fn device(&self) -> &Arc<Device> {
|
fn device(&self) -> &Arc<Device> {
|
||||||
self.semaphore.device()
|
self.semaphore.device()
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user