Add documentation and minor changes to instance

This commit is contained in:
Pierre Krieger 2016-09-18 14:00:02 +02:00
parent 109e5fc5e3
commit a5b5f89f95
3 changed files with 115 additions and 25 deletions

View File

@ -8,15 +8,16 @@
// according to those terms.
//! Debug callback called by validation layers.
//!
//!
//! When working on an application, it is recommended to register a debug callback. This callback
//! will be called by validation layers whenever necessary to warn you about invalid API usages
//! or performance problems.
//!
//! Note that the vulkano library can also emit messages to warn you about performance issues.
//!
//! TODO: ^ that's not the case yet, need to choose whether we keep this idea
//!
//! # Example
//!
//!
//! ```no_run
//! # use vulkano::instance::Instance;
//! # use std::sync::Arc;
@ -27,6 +28,11 @@
//! println!("Debug callback: {:?}", msg.description);
//! }).ok();
//! ```
//!
//! 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 `DebugCallback`'s constructor in a
//! variable, it will be immediately destroyed and your callback will not work.
//!
use std::error;
use std::ffi::CStr;
@ -48,6 +54,8 @@ use vk;
/// Registration of a callback called by validation layers.
///
/// The callback can be called as long as this object is alive.
#[must_use = "The DebugCallback object must be kept alive for as long as you want your callback \
to be called"]
pub struct DebugCallback {
instance: Arc<Instance>,
debug_report_callback: vk::DebugReportCallbackEXT,

View File

@ -326,6 +326,7 @@ pub enum InstanceCreationError {
/// One of the requested extensions is missing.
ExtensionNotPresent,
/// The version requested is not supported by the implementation.
// TODO: more info about this once the question of the version has been resolved
IncompatibleDriver,
}
@ -397,6 +398,9 @@ struct PhysicalDeviceInfos {
}
/// Represents one of the available devices on this machine.
///
/// This struct simply contains a pointer to an instance and a number representing the physical
/// device. You are therefore encouraged to pass this around by value instead of by reference.
#[derive(Debug, Copy, Clone)]
pub struct PhysicalDevice<'a> {
instance: &'a Arc<Instance>,
@ -414,6 +418,8 @@ impl<'a> PhysicalDevice<'a> {
}
/// Returns a physical device from its index. Returns `None` if out of range.
///
/// Indices range from 0 to the number of devices.
#[inline]
pub fn from_index(instance: &'a Arc<Instance>, index: usize) -> Option<PhysicalDevice<'a>> {
if instance.physical_devices.len() > index {
@ -556,6 +562,9 @@ impl<'a> PhysicalDevice<'a> {
}
/// Returns an opaque number representing the version of the driver of this device.
///
/// The meaning of this number is implementation-specific. It can be used in bug reports, for
/// example.
#[inline]
pub fn driver_version(&self) -> u32 {
self.infos().properties.driverVersion
@ -574,12 +583,15 @@ impl<'a> PhysicalDevice<'a> {
}
/// Returns a unique identifier for the device.
///
/// Can be stored in a configuration file, so that you can retrieve the device again the next
/// time the program is run.
#[inline]
pub fn uuid(&self) -> &[u8; 16] { // must be equal to vk::UUID_SIZE
&self.infos().properties.pipelineCacheUUID
}
/// Internal function to make it easier to get the infos of this device.
// Internal function to make it easier to get the infos of this device.
#[inline]
fn infos(&self) -> &'a PhysicalDeviceInfos {
&self.instance.physical_devices[self.device]
@ -619,6 +631,15 @@ impl<'a> Iterator for PhysicalDevicesIter<'a> {
self.current_id += 1;
Some(dev)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.instance.physical_devices.len() - self.current_id;
(len, Some(len))
}
}
impl<'a> ExactSizeIterator for PhysicalDevicesIter<'a> {
}
/// Type of a physical device.
@ -914,6 +935,8 @@ impl<'a> Iterator for MemoryHeapsIter<'a> {
}
}
impl<'a> ExactSizeIterator for MemoryHeapsIter<'a> {}
/// Limits of a physical device.
pub struct Limits<'a> {
device: PhysicalDevice<'a>,
@ -1041,8 +1064,6 @@ limits_impl!{
non_coherent_atom_size: u64 => nonCoherentAtomSize,
}
impl<'a> ExactSizeIterator for MemoryHeapsIter<'a> {}
#[cfg(test)]
mod tests {
use instance;

View File

@ -11,37 +11,98 @@
//!
//! The first thing to do before you start using Vulkan is to create an `Instance` object.
//!
//! Creating an instance initializes everything and allows you to:
//!
//! - Enumerate physical devices, ie. all the Vulkan implementations that are available on
//! the system.
//! - Enumerate monitors.
//! - Create surfaces (fullscreen or windowed) which will later be drawn upon.
//! For example:
//!
//! Enumerating monitors and creating surfaces can only be done if the proper extensions are
//! available and have been enabled. It is possible for a machine to support Vulkan without
//! support for rendering on a screen.
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let _instance = match Instance::new(None, &InstanceExtensions::none(), None) {
//! Ok(i) => i,
//! Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! Creating an instance initializes everything and allows you to enumerate physical devices,
//! ie. all the Vulkan implementations that are available on the system.
//!
//! ```no_run
//! # use vulkano::instance::Instance;
//! # use vulkano::instance::InstanceExtensions;
//! use vulkano::instance::PhysicalDevice;
//!
//! # let instance = Instance::new(None, &InstanceExtensions::none(), None).unwrap();
//! for physical_device in PhysicalDevice::enumerate(&instance) {
//! println!("Available device: {}", physical_device.name())
//! }
//! ```
//!
//! # Extensions
//!
//! Notice the second parameter of `Instance::new()`. It is an `InstanceExtensions` struct that
//! contains a list of extensions that must be enabled on the newly-created instance. Trying to
//! enable an extension that is not supported by the system will result in an error.
//!
//! Contrary to OpenGL, it is not possible to use the features of an extension if it was not
//! explicitly enabled.
//!
//! Extensions are especially important to take into account if you want to render images on the
//! screen, as the only way to do so is to use the `VK_KHR_surface` extension. More information
//! about this in the `swapchain` module.
//!
//! For example, here is how we create an instance with the `VK_KHR_surface` and
//! `VK_KHR_android_surface` extensions enabled, which will allow us to render images to an
//! Android screen. You can compile and run this code on any system, but it is highly unlikely to
//! succeed on anything else than an Android-running device.
//!
//! ```no_run
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! let extensions = InstanceExtensions {
//! khr_surface: true,
//! khr_android_surface: true,
//! .. InstanceExtensions::none()
//! };
//!
//! let _instance = match Instance::new(None, &extensions, None) {
//! Ok(i) => i,
//! Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
//! ```
//!
//! # Application info
//!
//! When you create an instance, you have the possibility to pass an `ApplicationInfo` struct. This
//! struct contains various information about your application, most notably its name and engine.
//!
//!
//! When you create an instance, you have the possibility to pass an `ApplicationInfo` struct as
//! the first parameter. This struct contains various information about your application, most
//! notably its name and engine.
//!
//! Passing such a structure allows for example the driver to let the user configure the driver's
//! behavior for your application alone through a control panel.
//!
//! # Enumerating physical devices
//! ```no_run
//! use vulkano::instance::ApplicationInfo;
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//!
//! After you have created an instance, the next step is to enumerate the physical devices that
//! are available on the system with `PhysicalDevice::enumerate()`.
//! // Builds an `ApplicationInfo` by looking at the content of the `Cargo.toml` file at
//! // compile-time.
//! let app_infos = ApplicationInfo::from_cargo_toml();
//!
//! let _instance = Instance::new(Some(&app_infos), &InstanceExtensions::none(), None).unwrap();
//! ```
//!
//! # Enumerating physical devices and creating a device
//!
//! After you have created an instance, the next step is usually to enumerate the physical devices
//! that are available on the system with `PhysicalDevice::enumerate()` (see above).
//!
//! When choosing which physical device to use, keep in mind that physical devices may or may not
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
//! to draw at all. See the `swapchain` module for more information about surfaces.
//!
//! A physical device can designate a video card, an integrated chip, but also multiple video
//! cards working together or a software implementation. Once you have chosen a physical device,
//! you can create a `Device` object from it. See the `device` module for more info.
//! Once you have chosen a physical device, you can create a `Device` object from it. See the
//! `device` module for more info.
//!
pub use features::Features;
pub use self::extensions::DeviceExtensions;