aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs243
1 files changed, 243 insertions, 0 deletions
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..8c8e7b2
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,243 @@
+// Copyright (c) 2016 The vulkano developers
+// Licensed under the Apache License, Version 2.0
+// <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
+// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
+// at your option. All files in the project carrying such
+// notice may not be copied, modified, or distributed except
+// according to those terms.
+
+#![doc(html_logo_url = "https://raw.githubusercontent.com/vulkano-rs/vulkano/master/logo.png")]
+//! Safe and rich Rust wrapper around the Vulkan API.
+//!
+//! # Brief summary of Vulkan
+//!
+//! - The [`Instance`](instance/struct.Instance.html) object is the API entry point. It is the
+//! first object you must create before starting to use Vulkan.
+//!
+//! - The [`PhysicalDevice`](instance/struct.PhysicalDevice.html) object represents an
+//! implementation of Vulkan available on the system (eg. a graphics card, a software
+//! implementation, etc.). Physical devices can be enumerated from an instance with
+//! [`PhysicalDevice::enumerate()`](instance/struct.PhysicalDevice.html#method.enumerate).
+//!
+//! - Once you have chosen a physical device to use, you can create a
+//! [`Device`](device/index.html) object from it. The `Device` is the most important
+//! object of Vulkan, as it represents an open channel of communication with a physical device.
+//! You always need to have one before you can do interesting things with Vulkan.
+//!
+//! - [*Buffers*](buffer/index.html) and [*images*](image/index.html) can be used to store data on
+//! memory accessible by the GPU (or more generally by the Vulkan implementation). Buffers are
+//! usually used to store information about vertices, lights, etc. or arbitrary data, while
+//! images are used to store textures or multi-dimensional data.
+//!
+//! - In order to show something on the screen, you need a [`Swapchain`](swapchain/index.html).
+//! A `Swapchain` contains special `Image`s that correspond to the content of the window or the
+//! monitor. When you *present* a swapchain, the content of one of these special images is shown
+//! on the screen.
+//!
+//! - In order to ask the GPU to do something, you must create a
+//! [*command buffer*](command_buffer/index.html). A command buffer contains a list of commands
+//! that the GPU must perform. This can include copies between buffers and images, compute
+//! operations, or graphics operations. For the work to start, the command buffer must then be
+//! submitted to a [`Queue`](device/struct.Queue.html), which is obtained when you create the
+//! `Device`.
+//!
+//! - In order to be able to add a compute operation or a graphics operation to a command buffer,
+//! you need to have created a [`ComputePipeline` or a `GraphicsPipeline`
+//! object](pipeline/index.html) that describes the operation you want. These objects are usually
+//! created during your program's initialization. `Shader`s are programs that the GPU will
+//! execute as part of a pipeline. [*Descriptors*](descriptor/index.html) can be used to access
+//! the content of buffers or images from within shaders.
+//!
+//! - For graphical operations, [`RenderPass`es and `Framebuffer`s](framebuffer/index.html)
+//! describe on which images the implementation must draw upon.
+//!
+//! - Once you have built a *command buffer* that contains a list of commands, submitting it to the
+//! GPU will return an object that implements [the `GpuFuture` trait](sync/index.html).
+//! `GpuFuture`s allow you to chain multiple submissions together and are essential to performing
+//! multiple operations on multiple different GPU queues.
+//!
+
+//#![warn(missing_docs)] // TODO: activate
+#![allow(dead_code)] // TODO: remove
+#![allow(unused_variables)] // TODO: remove
+
+pub use ash::vk::Handle;
+pub use half;
+use std::error;
+use std::fmt;
+use std::ops::Deref;
+use std::sync::Arc;
+use std::sync::MutexGuard;
+pub use version::Version;
+
+#[macro_use]
+mod tests;
+#[macro_use]
+mod extensions;
+pub mod buffer;
+pub mod command_buffer;
+pub mod descriptor_set;
+pub mod device;
+pub mod format;
+mod version;
+#[macro_use]
+pub mod render_pass;
+mod fns;
+pub mod image;
+pub mod instance;
+pub mod memory;
+pub mod pipeline;
+pub mod query;
+pub mod sampler;
+pub mod swapchain;
+pub mod sync;
+
+mod autogen {
+ // Generated by build.rs
+ include!(concat!(env!("OUT_DIR"), "/autogen.rs"));
+}
+
+/// Represents memory size and offset values on a Vulkan device.
+/// Analogous to the Rust `usize` type on the host.
+pub use ash::vk::DeviceSize;
+
+/// Alternative to the `Deref` trait. Contrary to `Deref`, must always return the same object.
+pub unsafe trait SafeDeref: Deref {}
+unsafe impl<'a, T: ?Sized> SafeDeref for &'a T {}
+unsafe impl<T: ?Sized> SafeDeref for Arc<T> {}
+unsafe impl<T: ?Sized> SafeDeref for Box<T> {}
+
+/// Gives access to the internal identifier of an object.
+pub unsafe trait VulkanObject {
+ /// The type of the object.
+ type Object: ash::vk::Handle;
+
+ /// Returns a reference to the object.
+ fn internal_object(&self) -> Self::Object;
+}
+
+/// Gives access to the internal identifier of an object.
+// TODO: remove ; crappy design
+pub unsafe trait SynchronizedVulkanObject {
+ /// The type of the object.
+ type Object: ash::vk::Handle;
+
+ /// Returns a reference to the object.
+ fn internal_object_guard(&self) -> MutexGuard<Self::Object>;
+}
+
+/// Error type returned by most Vulkan functions.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum OomError {
+ /// There is no memory available on the host (ie. the CPU, RAM, etc.).
+ OutOfHostMemory,
+ /// There is no memory available on the device (ie. video memory).
+ OutOfDeviceMemory,
+}
+
+impl error::Error for OomError {}
+
+impl fmt::Display for OomError {
+ #[inline]
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ write!(
+ fmt,
+ "{}",
+ match *self {
+ OomError::OutOfHostMemory => "no memory available on the host",
+ OomError::OutOfDeviceMemory => "no memory available on the graphical device",
+ }
+ )
+ }
+}
+
+impl From<Error> for OomError {
+ #[inline]
+ fn from(err: Error) -> OomError {
+ match err {
+ Error::OutOfHostMemory => OomError::OutOfHostMemory,
+ Error::OutOfDeviceMemory => OomError::OutOfDeviceMemory,
+ _ => panic!("unexpected error: {:?}", err),
+ }
+ }
+}
+
+/// All possible success codes returned by any Vulkan function.
+#[derive(Debug, Copy, Clone)]
+#[repr(i32)]
+enum Success {
+ Success = ash::vk::Result::SUCCESS.as_raw(),
+ NotReady = ash::vk::Result::NOT_READY.as_raw(),
+ Timeout = ash::vk::Result::TIMEOUT.as_raw(),
+ EventSet = ash::vk::Result::EVENT_SET.as_raw(),
+ EventReset = ash::vk::Result::EVENT_RESET.as_raw(),
+ Incomplete = ash::vk::Result::INCOMPLETE.as_raw(),
+ Suboptimal = ash::vk::Result::SUBOPTIMAL_KHR.as_raw(),
+}
+
+/// All possible errors returned by any Vulkan function.
+///
+/// This type is not public. Instead all public error types should implement `From<Error>` and
+/// panic for error code that aren't supposed to happen.
+#[derive(Debug, Copy, Clone)]
+#[repr(i32)]
+// TODO: being pub is necessary because of the weird visibility rules in rustc
+pub(crate) enum Error {
+ OutOfHostMemory = ash::vk::Result::ERROR_OUT_OF_HOST_MEMORY.as_raw(),
+ OutOfDeviceMemory = ash::vk::Result::ERROR_OUT_OF_DEVICE_MEMORY.as_raw(),
+ InitializationFailed = ash::vk::Result::ERROR_INITIALIZATION_FAILED.as_raw(),
+ DeviceLost = ash::vk::Result::ERROR_DEVICE_LOST.as_raw(),
+ MemoryMapFailed = ash::vk::Result::ERROR_MEMORY_MAP_FAILED.as_raw(),
+ LayerNotPresent = ash::vk::Result::ERROR_LAYER_NOT_PRESENT.as_raw(),
+ ExtensionNotPresent = ash::vk::Result::ERROR_EXTENSION_NOT_PRESENT.as_raw(),
+ FeatureNotPresent = ash::vk::Result::ERROR_FEATURE_NOT_PRESENT.as_raw(),
+ IncompatibleDriver = ash::vk::Result::ERROR_INCOMPATIBLE_DRIVER.as_raw(),
+ TooManyObjects = ash::vk::Result::ERROR_TOO_MANY_OBJECTS.as_raw(),
+ FormatNotSupported = ash::vk::Result::ERROR_FORMAT_NOT_SUPPORTED.as_raw(),
+ SurfaceLost = ash::vk::Result::ERROR_SURFACE_LOST_KHR.as_raw(),
+ NativeWindowInUse = ash::vk::Result::ERROR_NATIVE_WINDOW_IN_USE_KHR.as_raw(),
+ OutOfDate = ash::vk::Result::ERROR_OUT_OF_DATE_KHR.as_raw(),
+ IncompatibleDisplay = ash::vk::Result::ERROR_INCOMPATIBLE_DISPLAY_KHR.as_raw(),
+ ValidationFailed = ash::vk::Result::ERROR_VALIDATION_FAILED_EXT.as_raw(),
+ OutOfPoolMemory = ash::vk::Result::ERROR_OUT_OF_POOL_MEMORY_KHR.as_raw(),
+ FullscreenExclusiveLost = ash::vk::Result::ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT.as_raw(),
+}
+
+/// Checks whether the result returned correctly.
+fn check_errors(result: ash::vk::Result) -> Result<Success, Error> {
+ match result {
+ ash::vk::Result::SUCCESS => Ok(Success::Success),
+ ash::vk::Result::NOT_READY => Ok(Success::NotReady),
+ ash::vk::Result::TIMEOUT => Ok(Success::Timeout),
+ ash::vk::Result::EVENT_SET => Ok(Success::EventSet),
+ ash::vk::Result::EVENT_RESET => Ok(Success::EventReset),
+ ash::vk::Result::INCOMPLETE => Ok(Success::Incomplete),
+ ash::vk::Result::ERROR_OUT_OF_HOST_MEMORY => Err(Error::OutOfHostMemory),
+ ash::vk::Result::ERROR_OUT_OF_DEVICE_MEMORY => Err(Error::OutOfDeviceMemory),
+ ash::vk::Result::ERROR_INITIALIZATION_FAILED => Err(Error::InitializationFailed),
+ ash::vk::Result::ERROR_DEVICE_LOST => Err(Error::DeviceLost),
+ ash::vk::Result::ERROR_MEMORY_MAP_FAILED => Err(Error::MemoryMapFailed),
+ ash::vk::Result::ERROR_LAYER_NOT_PRESENT => Err(Error::LayerNotPresent),
+ ash::vk::Result::ERROR_EXTENSION_NOT_PRESENT => Err(Error::ExtensionNotPresent),
+ ash::vk::Result::ERROR_FEATURE_NOT_PRESENT => Err(Error::FeatureNotPresent),
+ ash::vk::Result::ERROR_INCOMPATIBLE_DRIVER => Err(Error::IncompatibleDriver),
+ ash::vk::Result::ERROR_TOO_MANY_OBJECTS => Err(Error::TooManyObjects),
+ ash::vk::Result::ERROR_FORMAT_NOT_SUPPORTED => Err(Error::FormatNotSupported),
+ ash::vk::Result::ERROR_SURFACE_LOST_KHR => Err(Error::SurfaceLost),
+ ash::vk::Result::ERROR_NATIVE_WINDOW_IN_USE_KHR => Err(Error::NativeWindowInUse),
+ ash::vk::Result::SUBOPTIMAL_KHR => Ok(Success::Suboptimal),
+ ash::vk::Result::ERROR_OUT_OF_DATE_KHR => Err(Error::OutOfDate),
+ ash::vk::Result::ERROR_INCOMPATIBLE_DISPLAY_KHR => Err(Error::IncompatibleDisplay),
+ ash::vk::Result::ERROR_VALIDATION_FAILED_EXT => Err(Error::ValidationFailed),
+ ash::vk::Result::ERROR_OUT_OF_POOL_MEMORY_KHR => Err(Error::OutOfPoolMemory),
+ ash::vk::Result::ERROR_FULL_SCREEN_EXCLUSIVE_MODE_LOST_EXT => {
+ Err(Error::FullscreenExclusiveLost)
+ }
+ ash::vk::Result::ERROR_INVALID_SHADER_NV => panic!(
+ "Vulkan function returned \
+ VK_ERROR_INVALID_SHADER_NV"
+ ),
+ c => unreachable!("Unexpected error code returned by Vulkan: {}", c),
+ }
+}