Add InstanceCreateInfo and DeviceCreateInfo (#1814)

* Convert creation of `Instance` and `Device` to use a builder

* Big oops

* Add `InstanceCreateInfo` and `DeviceCreateInfo`

* Doc fix

* impl FromStr for Version, remove elidable qf2
This commit is contained in:
Rua 2022-02-14 10:32:27 +01:00 committed by GitHub
parent 33aa520706
commit 8775777f47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
50 changed files with 1566 additions and 1418 deletions

View File

@ -17,16 +17,15 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
// As with other examples, the first step is to create an instance.
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
// Choose which physical device to use.
let device_extensions = DeviceExtensions {
@ -60,11 +59,13 @@ fn main() {
// Now initializing the device.
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -24,10 +24,10 @@ use std::time::{SystemTime, UNIX_EPOCH};
use vulkano::buffer::CpuBufferPool;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -35,7 +35,6 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -50,7 +49,11 @@ vulkano::impl_vertex!(Vertex, position);
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -85,11 +88,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -10,17 +10,16 @@
use std::sync::Arc;
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::ClearValue;
use vulkano::image::attachment::{ClearAttachment, ClearRect};
use vulkano::image::{view::ImageView, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::viewport::ViewportState;
use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -31,7 +30,11 @@ fn main() {
// `triangle` example if you haven't done so yet.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -66,11 +69,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -8,15 +8,14 @@
// according to those terms.
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageDimensions;
use vulkano::image::ImmutableImage;
use vulkano::image::MipmapsCount;
use vulkano::instance;
use vulkano::instance::debug::{DebugCallback, MessageSeverity, MessageType};
use vulkano::instance::{self, InstanceCreateInfo};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::Version;
fn main() {
// Vulkano Debugging Example Code
@ -51,14 +50,18 @@ fn main() {
// NOTE: To simplify the example code we won't verify these layer(s) are actually in the layers list:
#[cfg(not(target_os = "macos"))]
let layers = vec!["VK_LAYER_LUNARG_standard_validation"];
let layers = vec!["VK_LAYER_LUNARG_standard_validation".to_owned()];
#[cfg(target_os = "macos")]
let layers = vec!["VK_LAYER_KHRONOS_validation"];
let layers = vec!["VK_LAYER_KHRONOS_validation".to_owned()];
// Important: pass the extension(s) and layer(s) when creating the vulkano instance
let instance = Instance::new(None, Version::V1_1, &extensions, layers)
.expect("failed to create Vulkan instance");
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: extensions,
enabled_layers: layers,
..Default::default()
})
.expect("failed to create Vulkan instance");
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// After creating the instance we must register the debugging callback. //
@ -137,11 +140,13 @@ fn main() {
let (_, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
vec![(queue_family, 0.5)],
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.expect("failed to create device");
let queue = queues.next().unwrap();

View File

@ -31,15 +31,16 @@ use cgmath::Matrix4;
use cgmath::SquareMatrix;
use cgmath::Vector3;
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::DeviceCreateInfo;
use vulkano::device::QueueCreateInfo;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::image::view::ImageView;
use vulkano::image::ImageUsage;
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::swapchain;
use vulkano::swapchain::{AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync;
use vulkano::sync::{FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -52,7 +53,11 @@ fn main() {
// Basic initialization. See the triangle example if you want more details about this.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -87,11 +92,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -19,15 +19,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -57,11 +56,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -21,28 +21,25 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::{view::ImageView, ImageDimensions, StorageImage};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(
None,
Version::V1_1,
&InstanceExtensions {
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: InstanceExtensions {
// This extension is required to obtain physical device metadata
// about the device workgroup size limits
khr_get_physical_device_properties2: true,
..InstanceExtensions::none()
},
None,
)
..Default::default()
})
.unwrap();
let device_extensions = DeviceExtensions {
@ -72,11 +69,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -21,11 +21,11 @@ use vulkano::{
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
device::{
physical::{PhysicalDevice, PhysicalDeviceType},
Device, DeviceExtensions, Queue,
Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo,
},
format::Format,
image::{view::ImageView, ImageCreateFlags, ImageUsage, StorageImage, SwapchainImage},
instance::{debug::DebugCallback, Instance, InstanceExtensions},
instance::{debug::DebugCallback, Instance, InstanceCreateInfo, InstanceExtensions},
pipeline::{
graphics::color_blend::ColorBlendState,
graphics::input_assembly::{InputAssemblyState, PrimitiveTopology},
@ -37,7 +37,6 @@ use vulkano::{
sampler::{Filter, Sampler, SamplerAddressMode},
swapchain::{AcquireError, Swapchain, SwapchainCreationError},
sync::{now, FlushError, GpuFuture, PipelineStages, Semaphore},
Version,
};
#[cfg(target_os = "linux")]
use vulkano_win::VkSurfaceBuild;
@ -348,24 +347,21 @@ fn vk_setup(
Arc<GraphicsPipeline>,
Arc<CpuAccessibleBuffer<[Vertex]>>,
) {
use vulkano::device::Features;
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(
None,
Version::V1_2,
&(InstanceExtensions {
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: InstanceExtensions {
khr_get_physical_device_properties2: true,
khr_external_memory_capabilities: true,
khr_external_semaphore_capabilities: true,
khr_external_fence_capabilities: true,
ext_debug_utils: true,
..InstanceExtensions::none()
}
.union(&required_extensions)),
vec![],
)
.union(&required_extensions),
..Default::default()
})
.unwrap();
let _debug_callback = DebugCallback::errors_and_warnings(&instance, |msg| {
@ -384,7 +380,7 @@ fn vk_setup(
.build_vk_surface(&event_loop, instance.clone())
.unwrap();
let device_ext = DeviceExtensions {
let device_extensions = DeviceExtensions {
khr_external_semaphore: true,
khr_external_semaphore_fd: true,
khr_external_memory: true,
@ -396,7 +392,7 @@ fn vk_setup(
};
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
.filter(|&p| p.supported_extensions().is_superset_of(&device_ext))
.filter(|&p| p.supported_extensions().is_superset_of(&device_extensions))
.filter_map(|p| {
p.queue_families()
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
@ -426,9 +422,11 @@ fn vk_setup(
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&device_ext,
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: device_extensions,
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -15,11 +15,11 @@ use vulkano::command_buffer::{
};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::{ClearValue, Format};
use vulkano::image::{view::ImageView, ImageDimensions, ImageUsage, SwapchainImage};
use vulkano::image::{ImageAccess, StorageImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -29,7 +29,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -40,7 +39,11 @@ fn main() {
// `triangle` example if you haven't done so yet.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -75,11 +78,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -14,13 +14,13 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{
view::ImageView, ImageDimensions, ImageUsage, ImmutableImage, MipmapsCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -30,7 +30,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -41,7 +40,11 @@ fn main() {
// `triangle` example if you haven't done so yet.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -76,11 +79,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -13,18 +13,17 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, ImmutableBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
// The most part of this example is exactly the same as `basic-compute-shader`. You should read the
// `basic-compute-shader` example if you haven't done so yet.
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -54,11 +53,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -23,13 +23,13 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{
view::ImageView, ImageDimensions, ImageUsage, ImmutableImage, MipmapsCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -39,7 +39,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -47,7 +46,11 @@ use winit::window::{Window, WindowBuilder};
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -82,11 +85,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -38,10 +38,10 @@ use vulkano::command_buffer::{
};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -49,7 +49,6 @@ use vulkano::pipeline::{ComputePipeline, GraphicsPipeline, Pipeline, PipelineBin
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -66,7 +65,11 @@ impl_vertex!(Vertex, position);
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -102,11 +105,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -22,10 +22,10 @@ use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -33,7 +33,6 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -63,7 +62,11 @@ impl_vertex!(InstanceData, position_offset, scale);
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -98,11 +101,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -14,20 +14,22 @@ use vulkano_win::VkSurfaceBuild;
use std::collections::HashMap;
use std::sync::Arc;
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features, Queue};
use vulkano::device::{
Device, DeviceCreateInfo, DeviceExtensions, Features, Queue, QueueCreateInfo,
};
use vulkano::format::Format;
use vulkano::image::view::ImageView;
use vulkano::image::{
AttachmentImage, ImageAccess, ImageUsage, ImageViewAbstract, SampleCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::InstanceExtensions;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::swapchain::{
AcquireError, ColorSpace, FullscreenExclusive, PresentMode, Surface, SurfaceTransform,
Swapchain, SwapchainCreationError,
};
use vulkano::sync::{FlushError, GpuFuture};
use vulkano::{swapchain, sync, Version};
use vulkano::{swapchain, sync};
use winit::event_loop::EventLoop;
use winit::window::{Fullscreen, Window, WindowBuilder};
@ -86,11 +88,14 @@ impl Renderer {
..vulkano_win::required_extensions()
};
// Create instance
let _instance = Instance::new(None, Version::V1_2, &instance_extensions, None)
.expect("Failed to create instance");
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: instance_extensions,
..Default::default()
})
.expect("Failed to create instance");
// Get desired device
let physical_device = PhysicalDevice::enumerate(&_instance)
let physical_device = PhysicalDevice::enumerate(&instance)
.min_by_key(|p| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,
@ -108,7 +113,7 @@ impl Renderer {
opts.window_size[1],
))
.with_title(opts.title)
.build_vk_surface(event_loop, _instance.clone())
.build_vk_surface(event_loop, instance.clone())
.unwrap();
println!("Window scale factor {}", surface.window().scale_factor());
@ -134,7 +139,7 @@ impl Renderer {
};
Renderer {
_instance,
_instance: instance,
device,
surface,
queue,
@ -151,10 +156,10 @@ impl Renderer {
/// Creates vulkan device with required queue families and required extensions
fn create_device(
physical: PhysicalDevice,
physical_device: PhysicalDevice,
surface: Arc<Surface<Window>>,
) -> (Arc<Device>, Arc<Queue>) {
let queue_family = physical
let queue_family = physical_device
.queue_families()
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
.unwrap();
@ -170,15 +175,18 @@ impl Renderer {
fill_mode_non_solid: true,
..Features::none()
};
let (device, mut queues) = {
Device::new(
physical,
&features,
&physical.required_extensions().union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
)
.unwrap()
};
let (device, mut queues) = Device::new(
physical_device,
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
enabled_features: features,
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
(device, queues.next().unwrap())
}

View File

@ -73,24 +73,27 @@ use vulkano::command_buffer::{
AutoCommandBufferBuilder, CommandBufferUsage, PrimaryCommandBuffer, SubpassContents,
};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::ClearValue;
use vulkano::format::Format;
use vulkano::image::{
view::ImageView, AttachmentImage, ImageDimensions, SampleCount, StorageImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, Subpass};
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
// The usual Vulkan initialization.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let device_extensions = DeviceExtensions {
khr_swapchain: true,
@ -120,11 +123,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -21,10 +21,10 @@ use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -32,7 +32,6 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Surface, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::ElementState;
use winit::event::KeyboardInput;
@ -51,7 +50,11 @@ struct WindowSurface {
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
// A hashmap that contains all of our created windows and their resources
@ -95,13 +98,16 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
(
device,
queues.next().unwrap(),

View File

@ -19,7 +19,7 @@ pub struct VulkanoConfig {
pub instance_extensions: InstanceExtensions,
pub device_extensions: DeviceExtensions,
pub features: Features,
pub layers: Vec<&'static str>,
pub layers: Vec<String>,
}
impl Default for VulkanoConfig {

View File

@ -6,19 +6,22 @@
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::sync::Arc;
use std::{
ffi::{CStr, CString},
sync::Arc,
};
#[cfg(target_os = "macos")]
use vulkano::instance::InstanceCreationError;
use vulkano::{
device::{
physical::{PhysicalDevice, PhysicalDeviceType},
Device, DeviceExtensions, Features, Queue,
Device, DeviceCreateInfo, DeviceExtensions, Features, Queue, QueueCreateInfo,
},
image::{view::ImageView, ImageUsage},
instance::{
debug::{DebugCallback, MessageSeverity, MessageType},
Instance, InstanceExtensions,
Instance, InstanceCreateInfo, InstanceExtensions,
},
swapchain::{
ColorSpace, FullscreenExclusive, PresentMode, Surface, SurfaceTransform, Swapchain,
@ -55,11 +58,10 @@ unsafe impl Send for VulkanoContext {}
impl VulkanoContext {
pub fn new(config: &VulkanoConfig) -> Self {
let instance = create_vk_instance(config.instance_extensions, &config.layers);
let is_debug = config
.layers
.contains(&"VK_LAYER_LUNARG_standard_validation")
|| config.layers.contains(&"VK_LAYER_KHRONOS_validation");
let instance = create_vk_instance(config.instance_extensions, config.layers.clone());
let is_debug = config.layers.iter().any(|layer| {
layer == "VK_LAYER_LUNARG_standard_validation" || layer == "VK_LAYER_KHRONOS_validation"
});
let debug_callback = create_vk_debug_callback(&instance, is_debug);
// Get desired device
let physical_device = PhysicalDevice::enumerate(&instance)
@ -123,30 +125,39 @@ impl VulkanoContext {
// If we can create a compute queue, do so. Else use same queue as graphics
if let Some((_compute_index, queue_family_compute)) = compute_family_data {
let (device, mut queues) = {
Device::new(
physical,
&features,
&physical.required_extensions().union(&device_extensions),
[(queue_family_graphics, 1.0), (queue_family_compute, 0.5)]
.iter()
.cloned(),
)
.unwrap()
};
let (device, mut queues) = Device::new(
physical,
DeviceCreateInfo {
enabled_extensions: physical.required_extensions().union(&device_extensions),
enabled_features: features,
queue_create_infos: vec![
QueueCreateInfo {
queues: vec![1.0],
..QueueCreateInfo::family(queue_family_graphics)
},
QueueCreateInfo {
queues: vec![0.5],
..QueueCreateInfo::family(queue_family_compute)
},
],
..Default::default()
},
)
.unwrap();
let gfx_queue = queues.next().unwrap();
let compute_queue = queues.next().unwrap();
(device, gfx_queue, compute_queue)
} else {
let (device, mut queues) = {
Device::new(
physical,
&features,
&physical.required_extensions().union(&device_extensions),
[(queue_family_graphics, 1.0)].iter().cloned(),
)
.unwrap()
};
let (device, mut queues) = Device::new(
physical,
DeviceCreateInfo {
enabled_extensions: physical.required_extensions().union(&device_extensions),
enabled_features: features,
queue_create_infos: vec![QueueCreateInfo::family(queue_family_graphics)],
..Default::default()
},
)
.unwrap();
let gfx_queue = queues.next().unwrap();
let compute_queue = gfx_queue.clone();
(device, gfx_queue, compute_queue)
@ -222,29 +233,34 @@ impl VulkanoContext {
// Create vk instance with given layers
pub fn create_vk_instance(
instance_extensions: InstanceExtensions,
layers: &[&str],
layers: Vec<String>,
) -> Arc<Instance> {
// Create instance. On mac os, it will ask you to install vulkan sdk if you have not done so.
// Create instance.
let result = Instance::new(InstanceCreateInfo {
enabled_extensions: instance_extensions,
enabled_layers: layers,
..Default::default()
});
// Handle errors. On mac os, it will ask you to install vulkan sdk if you have not done so.
#[cfg(target_os = "macos")]
{
match Instance::new(None, Version::V1_2, &instance_extensions, layers.to_vec()) {
Err(e) => {
match e {
InstanceCreationError::LoadingError(le) => {
println!("{:?}, Did you install vulkanSDK from https://vulkan.lunarg.com/sdk/home ?", le);
Err(le).expect("")
}
_ => Err(e).expect("Failed to create instance"),
}
let instance = match result {
Err(e) => match e {
InstanceCreationError::LoadingError(le) => {
println!(
"{:?}, Did you install vulkanSDK from https://vulkan.lunarg.com/sdk/home ?",
le
);
Err(le).expect("")
}
Ok(i) => i,
}
}
_ => Err(e).expect("Failed to create instance"),
},
Ok(i) => i,
};
#[cfg(not(target_os = "macos"))]
{
Instance::new(None, Version::V1_2, &instance_extensions, layers.to_vec())
.expect("Failed to create instance")
}
let instance = result.expect("Failed to create instance");
instance
}
// Create vk debug call back (to exists outside renderer)

View File

@ -20,14 +20,14 @@ use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::view::ImageView;
use vulkano::image::{
ImageAccess, ImageCreateFlags, ImageDimensions, ImageLayout, ImageUsage, SampleCount,
StorageImage,
};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -37,19 +37,15 @@ use vulkano::render_pass::{
Subpass, SubpassDesc,
};
use vulkano::sync::{self, GpuFuture};
use vulkano::Version;
fn main() {
let instance = Instance::new(
None,
Version::V1_1,
&InstanceExtensions {
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: InstanceExtensions {
khr_get_physical_device_properties2: true, // required to get multiview limits
..InstanceExtensions::none()
},
None,
)
..Default::default()
})
.unwrap();
let device_extensions = DeviceExtensions {
@ -101,11 +97,14 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&features,
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
enabled_features: features,
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -15,11 +15,11 @@ use std::sync::Arc;
use vulkano::buffer::{BufferAccess, BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, DeviceOwned, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, DeviceOwned, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{view::ImageView, AttachmentImage, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::depth_stencil::DepthStencilState;
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -29,7 +29,6 @@ use vulkano::query::{QueryControlFlags, QueryPool, QueryResultFlags, QueryType};
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -37,7 +36,11 @@ use winit::window::{Window, WindowBuilder};
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -72,11 +75,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -32,15 +32,16 @@ use std::fs::File;
use std::io::Read;
use std::io::Write;
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::DeviceCreateInfo;
use vulkano::device::QueueCreateInfo;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::Instance;
use vulkano::pipeline::cache::PipelineCache;
use vulkano::pipeline::ComputePipeline;
use vulkano::Version;
fn main() {
// As with other examples, the first step is to create an instance.
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
// Choose which physical device to use.
let device_extensions = DeviceExtensions {
@ -72,11 +73,13 @@ fn main() {
// Now initializing the device.
let (device, _) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -13,15 +13,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -51,11 +50,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -14,13 +14,13 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::descriptor_set::WriteDescriptorSet;
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{
view::ImageView, ImageDimensions, ImageUsage, ImmutableImage, MipmapsCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -30,7 +30,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -38,7 +37,11 @@ use winit::window::{Window, WindowBuilder};
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -74,11 +77,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -26,10 +26,10 @@ use vulkano::buffer::cpu_access::CpuAccessibleBuffer;
use vulkano::buffer::{BufferUsage, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::rasterization::{CullMode, FrontFace, RasterizationState};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -39,7 +39,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::shader::ShaderModule;
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -56,7 +55,11 @@ vulkano::impl_vertex!(Vertex, position, color);
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -91,11 +94,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -17,13 +17,13 @@ use vulkano::descriptor_set::layout::{
};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{
view::ImageView, ImageDimensions, ImageUsage, ImmutableImage, MipmapsCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -33,7 +33,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::{Filter, Sampler, SamplerAddressMode};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -44,7 +43,11 @@ fn main() {
// `triangle` example if you haven't done so yet.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_2, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -79,17 +82,20 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features {
descriptor_indexing: true,
shader_uniform_buffer_array_non_uniform_indexing: true,
runtime_descriptor_array: true,
descriptor_binding_variable_descriptor_count: true,
..Features::none()
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
enabled_features: Features {
descriptor_indexing: true,
shader_uniform_buffer_array_non_uniform_indexing: true,
runtime_descriptor_array: true,
descriptor_binding_variable_descriptor_count: true,
..Features::none()
},
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -14,15 +14,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -52,11 +51,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -15,15 +15,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
..DeviceExtensions::none()
@ -52,11 +51,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -32,15 +32,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features, Queue};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -70,11 +69,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -13,15 +13,14 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::instance::{Instance, InstanceExtensions};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::instance::Instance;
use vulkano::pipeline::{ComputePipeline, Pipeline, PipelineBindPoint};
use vulkano::sync;
use vulkano::sync::GpuFuture;
use vulkano::Version;
fn main() {
let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
let instance = Instance::new(Default::default()).unwrap();
let device_extensions = DeviceExtensions {
khr_storage_buffer_storage_class: true,
@ -51,11 +50,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -16,12 +16,12 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::attachment::AttachmentImage;
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::depth_stencil::DepthStencilState;
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -31,7 +31,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::shader::ShaderModule;
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -42,7 +41,11 @@ fn main() {
// `triangle` example if you haven't done so yet.
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -77,11 +80,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -22,10 +22,10 @@ use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::rasterization::{PolygonMode, RasterizationState};
use vulkano::pipeline::graphics::tessellation::TessellationState;
@ -35,7 +35,6 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -138,7 +137,11 @@ mod fs {
fn main() {
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -179,11 +182,14 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&features,
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
enabled_features: features,
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -19,13 +19,13 @@ use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::format::Format;
use vulkano::image::ImageAccess;
use vulkano::image::{
view::ImageView, ImageDimensions, ImageUsage, ImmutableImage, MipmapsCount, SwapchainImage,
};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::color_blend::ColorBlendState;
use vulkano::pipeline::graphics::input_assembly::{InputAssemblyState, PrimitiveTopology};
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
@ -35,7 +35,6 @@ use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::sampler::Sampler;
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
fn main() {
@ -45,7 +44,11 @@ fn main() {
// uniform sampler2D array_of_textures[42];
let required_extensions = vulkano_win::required_extensions();
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
let event_loop = EventLoop::new();
let surface = WindowBuilder::new()
@ -80,11 +83,13 @@ fn main() {
let (device, mut queues) = Device::new(
physical_device,
&Features::none(),
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: physical_device
.required_extensions()
.union(&device_extensions),
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();
let queue = queues.next().unwrap();

View File

@ -20,10 +20,10 @@ use std::sync::Arc;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, TypedBufferAccess};
use vulkano::command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, SubpassContents};
use vulkano::device::physical::{PhysicalDevice, PhysicalDeviceType};
use vulkano::device::{Device, DeviceExtensions, Features};
use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use vulkano::image::view::ImageView;
use vulkano::image::{ImageAccess, ImageUsage, SwapchainImage};
use vulkano::instance::Instance;
use vulkano::instance::{Instance, InstanceCreateInfo};
use vulkano::pipeline::graphics::input_assembly::InputAssemblyState;
use vulkano::pipeline::graphics::vertex_input::BuffersDefinition;
use vulkano::pipeline::graphics::viewport::{Viewport, ViewportState};
@ -31,7 +31,6 @@ use vulkano::pipeline::GraphicsPipeline;
use vulkano::render_pass::{Framebuffer, RenderPass, Subpass};
use vulkano::swapchain::{self, AcquireError, Swapchain, SwapchainCreationError};
use vulkano::sync::{self, FlushError, GpuFuture};
use vulkano::Version;
use vulkano_win::VkSurfaceBuild;
use winit::event::{Event, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop};
@ -48,7 +47,11 @@ fn main() {
let required_extensions = vulkano_win::required_extensions();
// Now creating the instance.
let instance = Instance::new(None, Version::V1_1, &required_extensions, None).unwrap();
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: required_extensions,
..Default::default()
})
.unwrap();
// The objective of this example is to draw a triangle on a window. To do so, we first need to
// create the window.
@ -136,31 +139,28 @@ fn main() {
// Now initializing the device. This is probably the most important object of Vulkan.
//
// We have to pass four parameters when creating a device:
//
// - Which physical device to connect to.
//
// - A list of optional features and extensions that our program needs to work correctly.
// Some parts of the Vulkan specs are optional and must be enabled manually at device
// creation. In this example the only thing we are going to need is the `khr_swapchain`
// extension that allows us to draw to a window.
//
// - The list of queues that we are going to use. The exact parameter is an iterator whose
// items are `(Queue, f32)` where the floating-point represents the priority of the queue
// between 0.0 and 1.0. The priority of the queue is a hint to the implementation about how
// much it should prioritize queues between one another.
//
// The iterator of created queues is returned by the function alongside the device.
let (device, mut queues) = Device::new(
// Which physical device to connect to.
physical_device,
&Features::none(),
// Some devices require certain extensions to be enabled if they are present
// (e.g. `khr_portability_subset`). We add them to the device extensions that we're going to
// enable.
&physical_device
.required_extensions()
.union(&device_extensions),
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
// A list of optional features and extensions that our program needs to work correctly.
// Some parts of the Vulkan specs are optional and must be enabled manually at device
// creation. In this example the only thing we are going to need is the `khr_swapchain`
// extension that allows us to draw to a window.
enabled_extensions: physical_device
// Some devices require certain extensions to be enabled if they are present
// (e.g. `khr_portability_subset`). We add them to the device extensions that we're
// going to enable.
.required_extensions()
.union(&device_extensions),
// The list of queues that we are going to use. Here we only use one queue, from the
// previously chosen queue family.
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -25,6 +25,7 @@ fn requires_features(name: &str) -> &'static [&'static str] {
"sparseImageInt64Atomics" => &["shaderImageInt64Atomics"],
"sparseImageFloat32Atomics" => &["shaderImageFloat32Atomics"],
"sparseImageFloat32AtomicAdd" => &["shaderImageFloat32AtomicAdd"],
"sparseImageFloat32AtomicMinMax" => &["shaderImageFloat32AtomicMinMax"],
_ => &[],
}
}
@ -280,6 +281,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Features {
#(#struct_items)*
pub _ne: crate::NonExhaustive,
}
impl Features {
@ -298,6 +300,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
pub const fn none() -> Features {
Features {
#(#none_items)*
_ne: crate::NonExhaustive(()),
}
}
@ -308,6 +311,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
pub const fn all() -> Features {
Features {
#(#all_items)*
_ne: crate::NonExhaustive(()),
}
}
@ -326,6 +330,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
pub const fn intersection(&self, other: &Features) -> Features {
Features {
#(#intersection_items)*
_ne: crate::NonExhaustive(()),
}
}
@ -335,6 +340,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
pub const fn difference(&self, other: &Features) -> Features {
Features {
#(#difference_items)*
_ne: crate::NonExhaustive(()),
}
}
}
@ -349,6 +355,7 @@ fn features_output(members: &[FeaturesMember]) -> TokenStream {
fn from(features_ffi: &FeaturesFfi) -> Self {
Features {
#(#from_items)*
_ne: crate::NonExhaustive(()),
}
}
}

View File

@ -63,6 +63,7 @@ fn fns_output(extension_members: &[FnsMember], fns_level: &str) -> TokenStream {
quote! {
pub struct #struct_name {
#(#struct_items)*
pub _ne: crate::NonExhaustive,
}
impl #struct_name {
@ -71,9 +72,17 @@ fn fns_output(extension_members: &[FnsMember], fns_level: &str) -> TokenStream {
{
#struct_name {
#(#load_items)*
_ne: crate::NonExhaustive(()),
}
}
}
impl std::fmt::Debug for #struct_name {
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
Ok(())
}
}
}
}

View File

@ -247,6 +247,7 @@ fn formats_output(members: &[FormatMember]) -> TokenStream {
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[repr(i32)]
#[allow(non_camel_case_types)]
#[non_exhaustive]
pub enum Format {
#(#enum_items)*
}

View File

@ -108,12 +108,14 @@ fn properties_output(members: &[PropertiesMember]) -> TokenStream {
#[derive(Clone, Debug, Default)]
pub struct Properties {
#(#struct_items)*
pub _ne: crate::NonExhaustive,
}
impl From<&PropertiesFfi> for Properties {
fn from(properties_ffi: &PropertiesFfi) -> Self {
Properties {
#(#from_items)*
_ne: crate::NonExhaustive(()),
}
}
}

View File

@ -4188,9 +4188,7 @@ mod tests {
use crate::command_buffer::ExecuteCommandsError;
use crate::command_buffer::PrimaryCommandBuffer;
use crate::device::physical::PhysicalDevice;
use crate::device::Device;
use crate::device::DeviceExtensions;
use crate::device::Features;
use crate::device::{Device, DeviceCreateInfo, QueueCreateInfo};
use crate::sync::GpuFuture;
use std::sync::Arc;
@ -4210,9 +4208,10 @@ mod tests {
let (device, mut queues) = Device::new(
phys,
&Features::none(),
&DeviceExtensions::none(),
std::iter::once((queue_family, 0.5)),
DeviceCreateInfo {
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -38,6 +38,7 @@ use crate::VulkanObject;
/// Will use one Vulkan pool per thread in order to avoid locking. Will try to reuse command
/// buffers. Command buffers can't be moved between threads during the building process, but
/// finished command buffers can.
#[derive(Debug)]
pub struct StandardCommandPool {
// The device.
device: Arc<Device>,
@ -52,6 +53,7 @@ pub struct StandardCommandPool {
unsafe impl Send for StandardCommandPool {}
unsafe impl Sync for StandardCommandPool {}
#[derive(Debug)]
struct StandardCommandPoolPerThread {
// The Vulkan pool of this thread.
pool: Mutex<UnsafeCommandPool>,

View File

@ -29,11 +29,13 @@ use std::sync::Mutex;
/// Whenever a set is allocated, this implementation will try to find a pool that has some space
/// for it. If there is one, allocate from it. If there is none, create a new pool whose capacity
/// is 40 sets and 40 times the requested descriptors. This number is arbitrary.
#[derive(Debug)]
pub struct StdDescriptorPool {
device: Arc<Device>,
pools: Mutex<Vec<Arc<Mutex<Pool>>>>,
}
#[derive(Debug)]
struct Pool {
pool: UnsafeDescriptorPool,
remaining_capacity: DescriptorsCount,

View File

@ -15,16 +15,13 @@
//! Basic example:
//!
//! ```no_run
//! use vulkano::device::Device;
//! use vulkano::device::DeviceExtensions;
//! use vulkano::device::Features;
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//! use vulkano::device::physical::PhysicalDevice;
//! use vulkano::device::{Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo};
//! use vulkano::instance::{Instance, InstanceExtensions};
//! use vulkano::Version;
//!
//! // Creating the instance. See the documentation of the `instance` module.
//! let instance = match Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None) {
//! let instance = match Instance::new(Default::default()) {
//! Ok(i) => i,
//! Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
@ -37,9 +34,17 @@
//! let device = {
//! let queue_family = physical_device.queue_families().next().unwrap();
//! let features = Features::none();
//! let ext = DeviceExtensions::none();
//! let extensions = DeviceExtensions::none();
//!
//! match Device::new(physical_device, &features, &ext, Some((queue_family, 1.0))) {
//! match Device::new(
//! physical_device,
//! DeviceCreateInfo {
//! enabled_extensions: extensions,
//! enabled_features: features,
//! queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
//! ..Default::default()
//! },
//! ) {
//! Ok(d) => d,
//! Err(err) => panic!("Couldn't build device: {:?}", err)
//! }
@ -138,10 +143,11 @@ pub mod physical;
pub(crate) mod properties;
/// Represents a Vulkan context.
#[derive(Debug)]
pub struct Device {
handle: ash::vk::Device,
instance: Arc<Instance>,
physical_device: usize,
device: ash::vk::Device,
// The highest version that is supported for this device.
// This is the minimum of Instance::max_api_version and PhysicalDevice::api_version.
@ -152,9 +158,9 @@ pub struct Device {
standard_descriptor_pool: Mutex<Weak<StdDescriptorPool>>,
standard_command_pools:
Mutex<HashMap<u32, Weak<StandardCommandPool>, BuildHasherDefault<FnvHasher>>>,
features: Features,
extensions: DeviceExtensions,
active_queue_families: SmallVec<[u32; 8]>,
enabled_extensions: DeviceExtensions,
enabled_features: Features,
active_queue_families: SmallVec<[u32; 2]>,
allocation_count: Mutex<u32>,
fence_pool: Mutex<Vec<ash::vk::Fence>>,
semaphore_pool: Mutex<Vec<ash::vk::Semaphore>>,
@ -167,51 +173,119 @@ unsafe impl Send for Device {}
unsafe impl Sync for Device {}
impl Device {
/// Builds a new Vulkan device for the given physical device.
/// Creates a new `Device`.
///
/// You must pass two things when creating a logical device:
/// # Panics
///
/// - A list of optional Vulkan features that must be enabled on the device. Note that if a
/// feature is not enabled at device creation, you can't use it later even it it's supported
/// by the physical device.
///
/// - An iterator to a list of queues to create. Each element of the iterator must indicate
/// the family whose queue belongs to and a priority between 0.0 and 1.0 to assign to it.
/// A queue with a higher value indicates that the commands will execute faster than on a
/// queue with a lower value. Note however that no guarantee can be made on the way the
/// priority value is handled by the implementation.
///
/// # Panic
///
/// - Panics if one of the queue families doesn't belong to the given device.
///
// TODO: return Arc<Queue> and handle synchronization in the Queue
// TODO: Eliminate QueuesIter in favour of `impl ExactSizeIterator`. This doesn't currently work
// due to this Rust bug: https://github.com/rust-lang/rust/issues/42940. The compiler will
// erroneously assume that the return iterator borrows from 'a and break.
pub fn new<'a, I>(
/// - Panics if `create_info.queues` is empty.
/// - Panics if one of the queue families in `create_info.queues` doesn't belong to the given
/// physical device.
/// - Panics if `create_info.queues` contains multiple elements for the same queue family.
/// - Panics if `create_info.queues` contains an element where `queues` is empty.
/// - Panics if `create_info.queues` contains an element where `queues` contains a value that is
/// not between 0.0 and 1.0 inclusive.
pub fn new(
physical_device: PhysicalDevice,
requested_features: &Features,
requested_extensions: &DeviceExtensions,
queue_families: I,
) -> Result<(Arc<Device>, QueuesIter), DeviceCreationError>
where
I: IntoIterator<Item = (QueueFamily<'a>, f32)>,
{
create_info: DeviceCreateInfo,
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), DeviceCreationError> {
let DeviceCreateInfo {
enabled_extensions,
mut enabled_features,
queue_create_infos,
_ne: _,
} = create_info;
let instance = physical_device.instance();
let fns_i = instance.fns();
let api_version = physical_device.api_version();
// Check if the extensions are correct
requested_extensions.check_requirements(
/*
Queues
*/
struct QueueToGet {
family: u32,
id: u32,
}
// VUID-VkDeviceCreateInfo-queueCreateInfoCount-arraylength
assert!(!queue_create_infos.is_empty());
let mut queue_create_infos_vk: SmallVec<[_; 2]> =
SmallVec::with_capacity(queue_create_infos.len());
let mut active_queue_families: SmallVec<[_; 2]> =
SmallVec::with_capacity(queue_create_infos.len());
let mut queues_to_get: SmallVec<[_; 2]> = SmallVec::with_capacity(queue_create_infos.len());
for QueueCreateInfo {
family,
queues,
_ne: _,
} in &queue_create_infos
{
assert_eq!(
family.physical_device().internal_object(),
physical_device.internal_object()
);
// VUID-VkDeviceCreateInfo-queueFamilyIndex-02802
assert!(
queue_create_infos
.iter()
.filter(|qc2| qc2.family == *family)
.count()
== 1
);
// VUID-VkDeviceQueueCreateInfo-queueCount-arraylength
assert!(!queues.is_empty());
// VUID-VkDeviceQueueCreateInfo-pQueuePriorities-00383
assert!(queues
.iter()
.all(|&priority| priority >= 0.0 && priority <= 1.0));
if queues.len() > family.queues_count() {
return Err(DeviceCreationError::TooManyQueuesForFamily);
}
let family = family.id();
queue_create_infos_vk.push(ash::vk::DeviceQueueCreateInfo {
flags: ash::vk::DeviceQueueCreateFlags::empty(),
queue_family_index: family,
queue_count: queues.len() as u32,
p_queue_priorities: queues.as_ptr(), // borrows from queue_create
..Default::default()
});
active_queue_families.push(family);
queues_to_get.extend((0..queues.len() as u32).map(move |id| QueueToGet { family, id }));
}
active_queue_families.sort_unstable();
active_queue_families.dedup();
/*
Extensions
*/
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-01840
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-03328
// VUID-VkDeviceCreateInfo-pProperties-04451
enabled_extensions.check_requirements(
physical_device.supported_extensions(),
api_version,
instance.enabled_extensions(),
)?;
let mut requested_features = requested_features.clone();
let enabled_extensions_strings = Vec::<CString>::from(&enabled_extensions);
let enabled_extensions_ptrs = enabled_extensions_strings
.iter()
.map(|extension| extension.as_ptr())
.collect::<SmallVec<[_; 16]>>();
/*
Features
*/
// TODO: The plan regarding `robust_buffer_access` is to check the shaders' code to see
// if they can possibly perform out-of-bounds reads and writes. If the user tries
@ -229,156 +303,115 @@ impl Device {
//
// Note that if we ever remove this, don't forget to adjust the change in
// `Device`'s construction below.
requested_features.robust_buffer_access = true;
enabled_features.robust_buffer_access = true;
// Check if the features are correct
requested_features.check_requirements(
// VUID-VkDeviceCreateInfo-pNext-04748
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-04476
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02831
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02832
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02833
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02834
// VUID-VkDeviceCreateInfo-ppEnabledExtensionNames-02835
// VUID-VkDeviceCreateInfo-shadingRateImage-04478
// VUID-VkDeviceCreateInfo-shadingRateImage-04479
// VUID-VkDeviceCreateInfo-shadingRateImage-04480
// VUID-VkDeviceCreateInfo-fragmentDensityMap-04481
// VUID-VkDeviceCreateInfo-fragmentDensityMap-04482
// VUID-VkDeviceCreateInfo-fragmentDensityMap-04483
// VUID-VkDeviceCreateInfo-None-04896
// VUID-VkDeviceCreateInfo-None-04897
// VUID-VkDeviceCreateInfo-None-04898
// VUID-VkDeviceCreateInfo-sparseImageFloat32AtomicMinMax-04975
enabled_features.check_requirements(
physical_device.supported_features(),
api_version,
requested_extensions,
&enabled_extensions,
)?;
// device creation
let (device, queues) = unsafe {
// each element of `queues` is a `(queue_family, priorities)`
// each queue family must only have one entry in `queues`
let mut queues: Vec<(u32, Vec<f32>)> =
Vec::with_capacity(physical_device.queue_families().len());
// VUID-VkDeviceCreateInfo-pNext-02829
// VUID-VkDeviceCreateInfo-pNext-02830
// VUID-VkDeviceCreateInfo-pNext-06532
let mut features_ffi = FeaturesFfi::default();
features_ffi.make_chain(
api_version,
&enabled_extensions,
instance.enabled_extensions(),
);
features_ffi.write(&enabled_features);
// this variable will contain the queue family ID and queue ID of each requested queue
let mut output_queues: SmallVec<[(u32, u32); 8]> = SmallVec::new();
// Device layers were deprecated in Vulkan 1.0.13, and device layer requests should be
// ignored by the driver. For backwards compatibility, the spec recommends passing the
// exact instance layers to the device as well. There's no need to support separate
// requests at device creation time for legacy drivers: the spec claims that "[at] the
// time of deprecation there were no known device-only layers."
//
// Because there's no way to query the list of layers enabled for an instance, we need
// to save it alongside the instance. (`vkEnumerateDeviceLayerProperties` should get
// the right list post-1.0.13, but not pre-1.0.13, so we can't use it here.)
let enabled_layers_cstr: Vec<CString> = instance
.enabled_layers()
.iter()
.map(|name| CString::new(name.clone()).unwrap())
.collect();
let enabled_layers_ptrs = enabled_layers_cstr
.iter()
.map(|layer| layer.as_ptr())
.collect::<SmallVec<[_; 2]>>();
for (queue_family, priority) in queue_families {
// checking the parameters
assert_eq!(
queue_family.physical_device().internal_object(),
physical_device.internal_object()
);
if priority < 0.0 || priority > 1.0 {
return Err(DeviceCreationError::PriorityOutOfRange);
}
/*
Create the device
*/
// adding to `queues` and `output_queues`
if let Some(q) = queues.iter_mut().find(|q| q.0 == queue_family.id()) {
output_queues.push((queue_family.id(), q.1.len() as u32));
q.1.push(priority);
if q.1.len() > queue_family.queues_count() {
return Err(DeviceCreationError::TooManyQueuesForFamily);
}
continue;
}
queues.push((queue_family.id(), vec![priority]));
output_queues.push((queue_family.id(), 0));
}
let has_khr_get_physical_device_properties2 = instance
.enabled_extensions()
.khr_get_physical_device_properties2;
// turning `queues` into an array of `vkDeviceQueueCreateInfo` suitable for Vulkan
let queues = queues
.iter()
.map(
|&(queue_id, ref priorities)| ash::vk::DeviceQueueCreateInfo {
flags: ash::vk::DeviceQueueCreateFlags::empty(),
queue_family_index: queue_id,
queue_count: priorities.len() as u32,
p_queue_priorities: priorities.as_ptr(),
..Default::default()
},
)
.collect::<SmallVec<[_; 16]>>();
let mut create_info = ash::vk::DeviceCreateInfo {
flags: ash::vk::DeviceCreateFlags::empty(),
queue_create_info_count: queue_create_infos_vk.len() as u32,
p_queue_create_infos: queue_create_infos_vk.as_ptr(),
enabled_layer_count: enabled_layers_ptrs.len() as u32,
pp_enabled_layer_names: enabled_layers_ptrs.as_ptr(),
enabled_extension_count: enabled_extensions_ptrs.len() as u32,
pp_enabled_extension_names: enabled_extensions_ptrs.as_ptr(),
p_enabled_features: ptr::null(),
..Default::default()
};
let mut features_ffi = FeaturesFfi::default();
features_ffi.make_chain(
api_version,
requested_extensions,
instance.enabled_extensions(),
);
features_ffi.write(&requested_features);
// Device layers were deprecated in Vulkan 1.0.13, and device layer requests should be
// ignored by the driver. For backwards compatibility, the spec recommends passing the
// exact instance layers to the device as well. There's no need to support separate
// requests at device creation time for legacy drivers: the spec claims that "[at] the
// time of deprecation there were no known device-only layers."
//
// Because there's no way to query the list of layers enabled for an instance, we need
// to save it alongside the instance. (`vkEnumerateDeviceLayerProperties` should get
// the right list post-1.0.13, but not pre-1.0.13, so we can't use it here.)
let layers_ptrs = instance
.enabled_layers()
.map(|layer| layer.as_ptr())
.collect::<SmallVec<[_; 16]>>();
let extensions_strings: Vec<CString> = requested_extensions.into();
let extensions_ptrs = extensions_strings
.iter()
.map(|extension| extension.as_ptr())
.collect::<SmallVec<[_; 16]>>();
let has_khr_get_physical_device_properties2 = instance
.enabled_extensions()
.khr_get_physical_device_properties2;
let infos = ash::vk::DeviceCreateInfo {
p_next: if has_khr_get_physical_device_properties2 {
features_ffi.head_as_ref() as *const _ as _
} else {
ptr::null()
},
flags: ash::vk::DeviceCreateFlags::empty(),
queue_create_info_count: queues.len() as u32,
p_queue_create_infos: queues.as_ptr(),
enabled_layer_count: layers_ptrs.len() as u32,
pp_enabled_layer_names: layers_ptrs.as_ptr(),
enabled_extension_count: extensions_ptrs.len() as u32,
pp_enabled_extension_names: extensions_ptrs.as_ptr(),
p_enabled_features: if has_khr_get_physical_device_properties2 {
ptr::null()
} else {
&features_ffi.head_as_ref().features
},
..Default::default()
};
// VUID-VkDeviceCreateInfo-pNext-00373
if has_khr_get_physical_device_properties2 {
create_info.p_next = features_ffi.head_as_ref() as *const _ as _;
} else {
create_info.p_enabled_features = &features_ffi.head_as_ref().features;
}
let handle = unsafe {
let mut output = MaybeUninit::uninit();
check_errors(fns_i.v1_0.create_device(
physical_device.internal_object(),
&infos,
&create_info,
ptr::null(),
output.as_mut_ptr(),
))?;
(output.assume_init(), output_queues)
output.assume_init()
};
// loading the function pointers of the newly-created device
let fns = DeviceFunctions::load(|name| unsafe {
mem::transmute(fns_i.v1_0.get_device_proc_addr(device, name.as_ptr()))
mem::transmute(fns_i.v1_0.get_device_proc_addr(handle, name.as_ptr()))
});
let mut active_queue_families: SmallVec<[u32; 8]> = SmallVec::new();
for (queue_family, _) in queues.iter() {
if let None = active_queue_families
.iter()
.find(|&&qf| qf == *queue_family)
{
active_queue_families.push(*queue_family);
}
}
let device = Arc::new(Device {
handle,
instance: physical_device.instance().clone(),
physical_device: physical_device.index(),
device: device,
api_version,
fns,
standard_pool: Mutex::new(Weak::new()),
standard_descriptor_pool: Mutex::new(Weak::new()),
standard_command_pools: Mutex::new(Default::default()),
features: Features {
// Always enabled ; see above
robust_buffer_access: true,
..requested_features.clone()
},
extensions: requested_extensions.clone(),
enabled_extensions,
enabled_features,
active_queue_families,
allocation_count: Mutex::new(0),
fence_pool: Mutex::new(Vec::new()),
@ -386,14 +419,28 @@ impl Device {
event_pool: Mutex::new(Vec::new()),
});
// Iterator for the produced queues.
let queues = QueuesIter {
next_queue: 0,
device: device.clone(),
families_and_ids: queues,
// Iterator to return the queues
let queues_iter = {
let device = device.clone();
queues_to_get
.into_iter()
.map(move |QueueToGet { family, id }| unsafe {
let mut output = MaybeUninit::uninit();
device
.fns()
.v1_0
.get_device_queue(handle, family, id, output.as_mut_ptr());
Arc::new(Queue {
handle: Mutex::new(output.assume_init()),
device: device.clone(),
family,
id,
})
})
};
Ok((device, queues))
Ok((device, queues_iter))
}
/// Returns the Vulkan version supported by the device.
@ -424,7 +471,7 @@ impl Device {
/// while this function is waiting.
///
pub unsafe fn wait(&self) -> Result<(), OomError> {
check_errors(self.fns.v1_0.device_wait_idle(self.device))?;
check_errors(self.fns.v1_0.device_wait_idle(self.handle))?;
Ok(())
}
@ -452,16 +499,16 @@ impl Device {
.map(move |&id| physical_device.queue_family_by_id(id).unwrap())
}
/// Returns the features that have been enabled on the device.
#[inline]
pub fn enabled_features(&self) -> &Features {
&self.features
}
/// Returns the extensions that have been enabled on the device.
#[inline]
pub fn enabled_extensions(&self) -> &DeviceExtensions {
&self.extensions
&self.enabled_extensions
}
/// Returns the features that have been enabled on the device.
#[inline]
pub fn enabled_features(&self) -> &Features {
&self.enabled_features
}
/// Returns the standard memory pool used by default if you don't provide any other pool.
@ -578,28 +625,12 @@ impl Device {
self.instance
.fns()
.ext_debug_utils
.set_debug_utils_object_name_ext(self.device, &info),
.set_debug_utils_object_name_ext(self.handle, &info),
)?;
Ok(())
}
}
impl fmt::Debug for Device {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "<Vulkan device {:?}>", self.device)
}
}
unsafe impl VulkanObject for Device {
type Object = ash::vk::Device;
#[inline]
fn internal_object(&self) -> ash::vk::Device {
self.device
}
}
impl Drop for Device {
#[inline]
fn drop(&mut self) {
@ -607,27 +638,36 @@ impl Drop for Device {
for &raw_fence in self.fence_pool.lock().unwrap().iter() {
self.fns
.v1_0
.destroy_fence(self.device, raw_fence, ptr::null());
.destroy_fence(self.handle, raw_fence, ptr::null());
}
for &raw_sem in self.semaphore_pool.lock().unwrap().iter() {
self.fns
.v1_0
.destroy_semaphore(self.device, raw_sem, ptr::null());
.destroy_semaphore(self.handle, raw_sem, ptr::null());
}
for &raw_event in self.event_pool.lock().unwrap().iter() {
self.fns
.v1_0
.destroy_event(self.device, raw_event, ptr::null());
.destroy_event(self.handle, raw_event, ptr::null());
}
self.fns.v1_0.destroy_device(self.device, ptr::null());
self.fns.v1_0.destroy_device(self.handle, ptr::null());
}
}
}
unsafe impl VulkanObject for Device {
type Object = ash::vk::Device;
#[inline]
fn internal_object(&self) -> ash::vk::Device {
self.handle
}
}
impl PartialEq for Device {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.device == other.device && self.instance == other.instance
self.handle == other.handle && self.instance == other.instance
}
}
@ -636,11 +676,75 @@ impl Eq for Device {}
impl Hash for Device {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.device.hash(state);
self.handle.hash(state);
self.instance.hash(state);
}
}
/// Parameters to create a new `Device`.
#[derive(Clone, Debug)]
pub struct DeviceCreateInfo<'qf> {
/// The extensions to enable on the device.
///
/// The default value is [`DeviceExtensions::none()`].
pub enabled_extensions: DeviceExtensions,
/// The features to enable on the device.
///
/// The default value is [`Features::none()`].
pub enabled_features: Features,
/// The queues to create for the device.
///
/// The default value is empty, which must be overridden.
pub queue_create_infos: Vec<QueueCreateInfo<'qf>>,
pub _ne: crate::NonExhaustive,
}
impl Default for DeviceCreateInfo<'static> {
#[inline]
fn default() -> Self {
Self {
enabled_extensions: DeviceExtensions::none(),
enabled_features: Features::none(),
queue_create_infos: Vec::new(),
_ne: crate::NonExhaustive(()),
}
}
}
/// Parameters to create queues in a new `Device`.
#[derive(Clone, Debug)]
pub struct QueueCreateInfo<'qf> {
/// The queue family to create queues for.
pub family: QueueFamily<'qf>,
/// The queues to create for the given queue family, each with a relative priority.
///
/// The relative priority value is an arbitrary number between 0.0 and 1.0. Giving a queue a
/// higher priority is a hint to the driver that the queue should be given more processing time.
/// As this is only a hint, different drivers may handle this value differently and there are no
/// guarantees about its behavior.
///
/// The default value is a single queue with a priority of 0.5.
pub queues: Vec<f32>,
pub _ne: crate::NonExhaustive,
}
impl<'qf> QueueCreateInfo<'qf> {
/// Returns a `QueueCreateInfo` with the given queue family.
#[inline]
pub fn family(family: QueueFamily) -> QueueCreateInfo {
QueueCreateInfo {
family,
queues: vec![0.5],
_ne: crate::NonExhaustive(()),
}
}
}
/// Implemented on objects that belong to a Vulkan device.
///
/// # Safety
@ -663,57 +767,6 @@ where
}
}
/// Iterator that returns the queues produced when creating a device.
pub struct QueuesIter {
next_queue: usize,
device: Arc<Device>,
families_and_ids: SmallVec<[(u32, u32); 8]>,
}
unsafe impl DeviceOwned for QueuesIter {
fn device(&self) -> &Arc<Device> {
&self.device
}
}
impl Iterator for QueuesIter {
type Item = Arc<Queue>;
fn next(&mut self) -> Option<Arc<Queue>> {
unsafe {
let &(family, id) = match self.families_and_ids.get(self.next_queue) {
Some(a) => a,
None => return None,
};
self.next_queue += 1;
let mut output = MaybeUninit::uninit();
self.device.fns.v1_0.get_device_queue(
self.device.device,
family,
id,
output.as_mut_ptr(),
);
Some(Arc::new(Queue {
queue: Mutex::new(output.assume_init()),
device: self.device.clone(),
family: family,
id: id,
}))
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.families_and_ids.len().saturating_sub(self.next_queue);
(len, Some(len))
}
}
impl ExactSizeIterator for QueuesIter {}
/// Error that can be returned when creating a device.
#[derive(Copy, Clone, Debug)]
pub enum DeviceCreationError {
@ -820,7 +873,7 @@ impl From<FeatureRestrictionError> for DeviceCreationError {
// TODO: should use internal synchronization?
#[derive(Debug)]
pub struct Queue {
queue: Mutex<ash::vk::Queue>,
handle: Mutex<ash::vk::Queue>,
device: Arc<Device>,
family: u32,
id: u32, // id within family
@ -863,8 +916,8 @@ impl Queue {
pub fn wait(&self) -> Result<(), OomError> {
unsafe {
let fns = self.device.fns();
let queue = self.queue.lock().unwrap();
check_errors(fns.v1_0.queue_wait_idle(*queue))?;
let handle = self.handle.lock().unwrap();
check_errors(fns.v1_0.queue_wait_idle(*handle))?;
Ok(())
}
}
@ -888,17 +941,15 @@ unsafe impl SynchronizedVulkanObject for Queue {
type Object = ash::vk::Queue;
#[inline]
fn internal_object_guard(&self) -> MutexGuard<ash::vk::Queue> {
self.queue.lock().unwrap()
fn internal_object_guard(&self) -> MutexGuard<Self::Object> {
self.handle.lock().unwrap()
}
}
#[cfg(test)]
mod tests {
use crate::device::physical::PhysicalDevice;
use crate::device::Device;
use crate::device::DeviceCreationError;
use crate::device::DeviceExtensions;
use crate::device::{Device, DeviceCreateInfo, DeviceCreationError, QueueCreateInfo};
use crate::device::{FeatureRestriction, FeatureRestrictionError, Features};
use std::sync::Arc;
@ -921,9 +972,13 @@ mod tests {
match Device::new(
physical,
&Features::none(),
&DeviceExtensions::none(),
queues,
DeviceCreateInfo {
queue_create_infos: vec![QueueCreateInfo {
queues: (0..family.queues_count() + 1).map(|_| (0.5)).collect(),
..QueueCreateInfo::family(family)
}],
..Default::default()
},
) {
Err(DeviceCreationError::TooManyQueuesForFamily) => return, // Success
_ => panic!(),
@ -948,9 +1003,11 @@ mod tests {
match Device::new(
physical,
&features,
&DeviceExtensions::none(),
Some((family, 1.0)),
DeviceCreateInfo {
enabled_features: features,
queue_create_infos: vec![QueueCreateInfo::family(family)],
..Default::default()
},
) {
Err(DeviceCreationError::FeatureRestrictionNotMet(FeatureRestrictionError {
restriction: FeatureRestriction::NotSupported,
@ -970,24 +1027,30 @@ mod tests {
let family = physical.queue_families().next().unwrap();
match Device::new(
physical,
&Features::none(),
&DeviceExtensions::none(),
Some((family, 1.4)),
) {
Err(DeviceCreationError::PriorityOutOfRange) => (), // Success
_ => panic!(),
};
assert_should_panic!({
Device::new(
physical,
DeviceCreateInfo {
queue_create_infos: vec![QueueCreateInfo {
queues: vec![1.4],
..QueueCreateInfo::family(family)
}],
..Default::default()
},
)
});
match Device::new(
physical,
&Features::none(),
&DeviceExtensions::none(),
Some((family, -0.2)),
) {
Err(DeviceCreationError::PriorityOutOfRange) => (), // Success
_ => panic!(),
};
assert_should_panic!({
Device::new(
physical,
DeviceCreateInfo {
queue_create_infos: vec![QueueCreateInfo {
queues: vec![-0.2],
..QueueCreateInfo::family(family)
}],
..Default::default()
},
)
});
}
}

View File

@ -288,7 +288,7 @@ fn init_info2(instance: &Instance, info: &mut PhysicalDeviceInfo) {
/// # use vulkano::Version;
/// use vulkano::device::physical::PhysicalDevice;
///
/// # let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
/// # let instance = Instance::new(Default::default()).unwrap();
/// for physical_device in PhysicalDevice::enumerate(&instance) {
/// print_infos(physical_device);
/// }
@ -315,7 +315,7 @@ impl<'a> PhysicalDevice<'a> {
/// # use vulkano::Version;
/// use vulkano::device::physical::PhysicalDevice;
///
/// # let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
/// # let instance = Instance::new(Default::default()).unwrap();
/// for physical_device in PhysicalDevice::enumerate(&instance) {
/// println!("Available device: {}", physical_device.properties().device_name);
/// }
@ -347,7 +347,7 @@ impl<'a> PhysicalDevice<'a> {
/// use vulkano::device::physical::PhysicalDevice;
/// use vulkano::Version;
///
/// let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
/// let instance = Instance::new(Default::default()).unwrap();
/// let first_physical_device = PhysicalDevice::from_index(&instance, 0).unwrap();
/// ```
#[inline]
@ -470,6 +470,7 @@ impl<'a> PhysicalDevice<'a> {
linear_tiling_features: format_properties3.linear_tiling_features.into(),
optimal_tiling_features: format_properties3.optimal_tiling_features.into(),
buffer_features: format_properties3.buffer_features.into(),
_ne: crate::NonExhaustive(()),
},
None => FormatProperties {
linear_tiling_features: format_properties2
@ -481,6 +482,7 @@ impl<'a> PhysicalDevice<'a> {
.optimal_tiling_features
.into(),
buffer_features: format_properties2.format_properties.buffer_features.into(),
_ne: crate::NonExhaustive(()),
},
}
}
@ -1064,6 +1066,8 @@ pub struct SubgroupFeatures {
pub clustered: bool,
pub quad: bool,
pub partitioned: bool,
pub _ne: crate::NonExhaustive,
}
impl From<ash::vk::SubgroupFeatureFlags> for SubgroupFeatures {
@ -1079,6 +1083,8 @@ impl From<ash::vk::SubgroupFeatureFlags> for SubgroupFeatures {
clustered: val.intersects(ash::vk::SubgroupFeatureFlags::CLUSTERED),
quad: val.intersects(ash::vk::SubgroupFeatureFlags::QUAD),
partitioned: val.intersects(ash::vk::SubgroupFeatureFlags::PARTITIONED_NV),
_ne: crate::NonExhaustive(()),
}
}
}
@ -1152,6 +1158,8 @@ pub struct FormatProperties {
/// Features available for buffers.
pub buffer_features: FormatFeatures,
pub _ne: crate::NonExhaustive,
}
/// The features supported by a device for an image or buffer with a particular format.
@ -1250,6 +1258,8 @@ pub struct FormatFeatures {
pub vertex_buffer: bool,
/// Can be used with the vertex buffer of an acceleration structure.
pub acceleration_structure_vertex_buffer: bool,
pub _ne: crate::NonExhaustive,
}
impl BitOr for &FormatFeatures {
@ -1312,6 +1322,8 @@ impl BitOr for &FormatFeatures {
vertex_buffer: self.vertex_buffer || rhs.vertex_buffer,
acceleration_structure_vertex_buffer: self.acceleration_structure_vertex_buffer
|| rhs.acceleration_structure_vertex_buffer,
_ne: crate::NonExhaustive(()),
}
}
}
@ -1359,6 +1371,8 @@ impl From<ash::vk::FormatFeatureFlags> for FormatFeatures {
storage_texel_buffer_atomic: val.intersects(ash::vk::FormatFeatureFlags::STORAGE_TEXEL_BUFFER_ATOMIC),
vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags::VERTEX_BUFFER),
acceleration_structure_vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags::ACCELERATION_STRUCTURE_VERTEX_BUFFER_KHR),
_ne: crate::NonExhaustive(()),
}
}
}
@ -1406,6 +1420,8 @@ impl From<ash::vk::FormatFeatureFlags2KHR> for FormatFeatures {
storage_texel_buffer_atomic: val.intersects(ash::vk::FormatFeatureFlags2KHR::STORAGE_TEXEL_BUFFER_ATOMIC),
vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags2KHR::VERTEX_BUFFER),
acceleration_structure_vertex_buffer: val.intersects(ash::vk::FormatFeatureFlags2KHR::ACCELERATION_STRUCTURE_VERTEX_BUFFER),
_ne: crate::NonExhaustive(()),
}
}
}
@ -1415,23 +1431,30 @@ impl From<ash::vk::FormatFeatureFlags2KHR> for FormatFeatures {
pub struct ImageFormatProperties {
/// The maximum dimensions.
pub max_extent: [u32; 3],
/// The maximum number of mipmap levels.
pub max_mip_levels: u32,
/// The maximum number of array layers.
pub max_array_layers: u32,
/// The supported sample counts.
pub sample_counts: SampleCounts,
/// The maximum total size of an image, in bytes. This is guaranteed to be at least
/// 0x80000000.
pub max_resource_size: DeviceSize,
/// When querying with an image view type, whether such image views support sampling with
/// a [`Cubic`](crate::sampler::Filter::Cubic) `mag_filter` or `min_filter`.
pub filter_cubic: bool,
/// When querying with an image view type, whether such image views support sampling with
/// a [`Cubic`](crate::sampler::Filter::Cubic) `mag_filter` or `min_filter`, and with a
/// [`Min`](crate::sampler::SamplerReductionMode::Min) or
/// [`Max`](crate::sampler::SamplerReductionMode::Max) `reduction_mode`.
pub filter_cubic_minmax: bool,
pub _ne: crate::NonExhaustive,
}
impl From<ash::vk::ImageFormatProperties> for ImageFormatProperties {
@ -1448,6 +1471,8 @@ impl From<ash::vk::ImageFormatProperties> for ImageFormatProperties {
max_resource_size: props.max_resource_size,
filter_cubic: false,
filter_cubic_minmax: false,
_ne: crate::NonExhaustive(()),
}
}
}

View File

@ -1,692 +0,0 @@
// 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.
use crate::check_errors;
use crate::device::physical::{init_physical_devices, PhysicalDeviceInfo};
use crate::extensions::ExtensionRestrictionError;
use crate::fns::InstanceFunctions;
use crate::instance::loader;
use crate::instance::loader::FunctionPointers;
use crate::instance::loader::Loader;
use crate::instance::loader::LoadingError;
use crate::instance::InstanceExtensions;
use crate::Error;
use crate::OomError;
use crate::Version;
use crate::VulkanObject;
use smallvec::SmallVec;
use std::borrow::Cow;
use std::error;
use std::ffi::CString;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::mem::MaybeUninit;
use std::ops::Deref;
use std::ptr;
use std::slice;
use std::sync::Arc;
/// An instance of a Vulkan context. This is the main object that should be created by an
/// application before everything else.
///
/// # Application info
///
/// 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.
///
/// ```no_run
/// # #[macro_use] extern crate vulkano;
/// # fn main() {
/// use vulkano::instance::{Instance, InstanceExtensions};
/// use vulkano::Version;
///
/// // Builds an `ApplicationInfo` by looking at the content of the `Cargo.toml` file at
/// // compile-time.
/// let app_infos = app_info_from_cargo_toml!();
///
/// let _instance = Instance::new(Some(&app_infos), Version::V1_1, &InstanceExtensions::none(), None).unwrap();
/// # }
/// ```
///
/// # API versions
///
/// Both an `Instance` and a [`Device`](crate::device::Device) have a highest version of the Vulkan
/// API that they support. This places a limit on what Vulkan functions and features are available
/// to use when used on a particular instance or device. It is possible for the instance and the
/// device to support different versions. The supported version for an instance can be queried
/// before creation with
/// [`FunctionPointers::api_version`](crate::instance::loader::FunctionPointers::api_version),
/// while for a device it can be retrieved with
/// [`PhysicalDevice::api_version`](crate::device::physical::PhysicalDevice::api_version).
///
/// When creating an `Instance`, you have to specify a maximum API version that you will use.
/// This restricts the API version that is available for the instance and any devices created from
/// it. For example, if both instance and device potentially support Vulkan 1.2, but you specify
/// 1.1 as the maximum API version when creating the `Instance`, then you can only use Vulkan 1.1
/// functions, even though they could theoretically support a higher version. You can think of it
/// as a promise never to use any functionality from a higher version.
///
/// The maximum API version is not a _minimum_, so it is possible to set it to a higher version than
/// what the instance or device inherently support. The final API version that you are able to use
/// on an instance or device is the lower of the supported API version and the chosen maximum API
/// version of the `Instance`.
///
/// However, due to a quirk in how the Vulkan 1.0 specification was written, if the instance only
/// supports Vulkan 1.0, then it is not possible to specify a maximum API version higher than 1.0.
/// Trying to create an `Instance` will return an `IncompatibleDriver` error. Consequently, it is
/// not possible to use a higher device API version with an instance that only supports 1.0.
///
/// # Extensions
///
/// When creating an `Instance`, you must provide 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;
/// use vulkano::Version;
///
/// let extensions = InstanceExtensions {
/// khr_surface: true,
/// khr_android_surface: true,
/// .. InstanceExtensions::none()
/// };
///
/// let instance = match Instance::new(None, Version::V1_1, &extensions, None) {
/// Ok(i) => i,
/// Err(err) => panic!("Couldn't build instance: {:?}", err)
/// };
/// ```
///
/// # Layers
///
/// When creating an `Instance`, you have the possibility to pass a list of **layers** that will
/// be activated on the newly-created instance. The list of available layers can be retrieved by
/// calling [the `layers_list` function](crate::instance::layers_list).
///
/// A layer is a component that will hook and potentially modify the Vulkan function calls.
/// For example, activating a layer could add a frames-per-second counter on the screen, or it
/// could send information to a debugger that will debug your application.
///
/// > **Note**: From an application's point of view, layers "just exist". In practice, on Windows
/// > and Linux, layers can be installed by third party installers or by package managers and can
/// > also be activated by setting the value of the `VK_INSTANCE_LAYERS` environment variable
/// > before starting the program. See the documentation of the official Vulkan loader for these
/// > platforms.
///
/// > **Note**: In practice, the most common use of layers right now is for debugging purposes.
/// > To do so, you are encouraged to set the `VK_INSTANCE_LAYERS` environment variable on Windows
/// > or Linux instead of modifying the source code of your program. For example:
/// > `export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_api_dump` on Linux if you installed the Vulkan SDK
/// > will print the list of raw Vulkan function calls.
///
/// ## Example
///
/// ```
/// # use std::sync::Arc;
/// # use std::error::Error;
/// # use vulkano::instance;
/// # use vulkano::instance::Instance;
/// # use vulkano::instance::InstanceExtensions;
/// # use vulkano::Version;
/// # fn test() -> Result<Arc<Instance>, Box<dyn Error>> {
/// // For the sake of the example, we activate all the layers that
/// // contain the word "foo" in their description.
/// let layers: Vec<_> = instance::layers_list()?
/// .filter(|l| l.description().contains("foo"))
/// .collect();
///
/// let layer_names = layers.iter()
/// .map(|l| l.name());
///
/// let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), layer_names)?;
/// # Ok(instance)
/// # }
/// ```
// TODO: mention that extensions must be supported by layers as well
pub struct Instance {
instance: ash::vk::Instance,
//alloc: Option<Box<Alloc + Send + Sync>>,
// The highest version that is supported for this instance.
// This is the minimum of Instance::max_api_version and FunctionPointers::api_version.
api_version: Version,
// The highest allowed API version for instances and devices created from it.
max_api_version: Version,
pub(crate) physical_device_infos: Vec<PhysicalDeviceInfo>,
fns: InstanceFunctions,
extensions: InstanceExtensions,
layers: SmallVec<[CString; 16]>,
function_pointers: OwnedOrRef<FunctionPointers<Box<dyn Loader + Send + Sync>>>,
}
// TODO: fix the underlying cause instead
impl ::std::panic::UnwindSafe for Instance {}
impl ::std::panic::RefUnwindSafe for Instance {}
impl Instance {
/// Initializes a new instance of Vulkan.
///
/// See the documentation of `Instance` or of [the `instance` module](crate::instance) for more
/// details.
///
/// # Example
///
/// ```no_run
/// use vulkano::instance::Instance;
/// use vulkano::instance::InstanceExtensions;
/// use vulkano::Version;
///
/// let instance = match Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None) {
/// Ok(i) => i,
/// Err(err) => panic!("Couldn't build instance: {:?}", err)
/// };
/// ```
///
/// # Panic
///
/// - Panics if the version numbers passed in `ApplicationInfo` are too large can't be
/// converted into a Vulkan version number.
/// - Panics if the application name or engine name contain a null character.
// TODO: add a test for these ^
// TODO: if no allocator is specified by the user, use Rust's allocator instead of leaving
// the choice to Vulkan
pub fn new<'a, L>(
app_infos: Option<&ApplicationInfo>,
max_api_version: Version,
extensions: &InstanceExtensions,
layers: L,
) -> Result<Arc<Instance>, InstanceCreationError>
where
L: IntoIterator<Item = &'a str>,
{
let layers = layers
.into_iter()
.map(|layer| CString::new(layer).unwrap())
.collect::<SmallVec<[_; 16]>>();
Instance::new_inner(
app_infos,
max_api_version,
extensions,
layers,
OwnedOrRef::Ref(loader::auto_loader()?),
)
}
/// Same as `new`, but allows specifying a loader where to load Vulkan from.
pub fn with_loader<'a, L>(
loader: FunctionPointers<Box<dyn Loader + Send + Sync>>,
app_infos: Option<&ApplicationInfo>,
max_api_version: Version,
extensions: &InstanceExtensions,
layers: L,
) -> Result<Arc<Instance>, InstanceCreationError>
where
L: IntoIterator<Item = &'a str>,
{
let layers = layers
.into_iter()
.map(|layer| CString::new(layer).unwrap())
.collect::<SmallVec<[_; 16]>>();
Instance::new_inner(
app_infos,
max_api_version,
extensions,
layers,
OwnedOrRef::Owned(loader),
)
}
fn new_inner(
app_infos: Option<&ApplicationInfo>,
max_api_version: Version,
extensions: &InstanceExtensions,
layers: SmallVec<[CString; 16]>,
function_pointers: OwnedOrRef<FunctionPointers<Box<dyn Loader + Send + Sync>>>,
) -> Result<Arc<Instance>, InstanceCreationError> {
let api_version = std::cmp::min(max_api_version, function_pointers.api_version()?);
// Check if the extensions are correct
extensions.check_requirements(
&InstanceExtensions::supported_by_core_with_loader(&function_pointers)?,
api_version,
)?;
// TODO: For now there are still buggy drivers that will segfault if you don't pass any
// appinfos. Therefore for now we ensure that it can't be `None`.
let def = Default::default();
let app_infos = match app_infos {
Some(a) => Some(a),
None => Some(&def),
};
// Building the CStrings from the `str`s within `app_infos`.
// They need to be created ahead of time, since we pass pointers to them.
let app_infos_strings = if let Some(app_infos) = app_infos {
Some((
app_infos
.application_name
.clone()
.map(|n| CString::new(n.as_bytes().to_owned()).unwrap()),
app_infos
.engine_name
.clone()
.map(|n| CString::new(n.as_bytes().to_owned()).unwrap()),
))
} else {
None
};
// Building the `vk::ApplicationInfo` if required.
let app_infos = if let Some(app_infos) = app_infos {
Some(ash::vk::ApplicationInfo {
p_application_name: app_infos_strings
.as_ref()
.unwrap()
.0
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or(ptr::null()),
application_version: app_infos
.application_version
.map(|v| v.try_into().expect("Version out of range"))
.unwrap_or(0),
p_engine_name: app_infos_strings
.as_ref()
.unwrap()
.1
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or(ptr::null()),
engine_version: app_infos
.engine_version
.map(|v| v.try_into().expect("Version out of range"))
.unwrap_or(0),
api_version: max_api_version.try_into().expect("Version out of range"),
..Default::default()
})
} else {
None
};
// FIXME: check whether each layer is supported
let layers_ptrs = layers
.iter()
.map(|layer| layer.as_ptr())
.collect::<SmallVec<[_; 16]>>();
let extensions_list: Vec<CString> = extensions.into();
let extensions_ptrs = extensions_list
.iter()
.map(|extension| extension.as_ptr())
.collect::<SmallVec<[_; 32]>>();
// Creating the Vulkan instance.
let instance = unsafe {
let mut output = MaybeUninit::uninit();
let infos = ash::vk::InstanceCreateInfo {
flags: ash::vk::InstanceCreateFlags::empty(),
p_application_info: if let Some(app) = app_infos.as_ref() {
app as *const _
} else {
ptr::null()
},
enabled_layer_count: layers_ptrs.len() as u32,
pp_enabled_layer_names: layers_ptrs.as_ptr(),
enabled_extension_count: extensions_ptrs.len() as u32,
pp_enabled_extension_names: extensions_ptrs.as_ptr(),
..Default::default()
};
let fns = function_pointers.fns();
check_errors(
fns.v1_0
.create_instance(&infos, ptr::null(), output.as_mut_ptr()),
)?;
output.assume_init()
};
// Loading the function pointers of the newly-created instance.
let fns = {
InstanceFunctions::load(|name| {
function_pointers.get_instance_proc_addr(instance, name.as_ptr())
})
};
let mut instance = Instance {
instance,
api_version,
max_api_version,
//alloc: None,
physical_device_infos: Vec::new(),
fns,
extensions: extensions.clone(),
layers,
function_pointers,
};
// Enumerating all physical devices.
instance.physical_device_infos = init_physical_devices(&instance)?;
Ok(Arc::new(instance))
}
/*/// Same as `new`, but provides an allocator that will be used by the Vulkan library whenever
/// it needs to allocate memory on the host.
///
/// Note that this allocator can be overridden when you create a `Device`, a `MemoryPool`, etc.
pub fn with_alloc(app_infos: Option<&ApplicationInfo>, alloc: Box<Alloc + Send + Sync>) -> Arc<Instance> {
unimplemented!()
}*/
/// Returns the Vulkan version supported by the instance.
///
/// This is the lower of the
/// [driver's supported version](crate::instance::loader::FunctionPointers::api_version) and
/// [`max_api_version`](Instance::max_api_version).
#[inline]
pub fn api_version(&self) -> Version {
self.api_version
}
/// Returns the maximum Vulkan version that was specified when creating the instance.
#[inline]
pub fn max_api_version(&self) -> Version {
self.max_api_version
}
/// Grants access to the Vulkan functions of the instance.
#[inline]
pub fn fns(&self) -> &InstanceFunctions {
&self.fns
}
/// Returns the extensions that have been enabled on the instance.
#[inline]
pub fn enabled_extensions(&self) -> &InstanceExtensions {
&self.extensions
}
/// Returns the layers that have been enabled on the instance.
#[doc(hidden)]
#[inline]
pub fn enabled_layers(&self) -> slice::Iter<CString> {
self.layers.iter()
}
}
impl fmt::Debug for Instance {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(fmt, "<Vulkan instance {:?}>", self.instance)
}
}
unsafe impl VulkanObject for Instance {
type Object = ash::vk::Instance;
#[inline]
fn internal_object(&self) -> ash::vk::Instance {
self.instance
}
}
impl Drop for Instance {
#[inline]
fn drop(&mut self) {
unsafe {
self.fns.v1_0.destroy_instance(self.instance, ptr::null());
}
}
}
impl PartialEq for Instance {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.instance == other.instance
}
}
impl Eq for Instance {}
impl Hash for Instance {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.instance.hash(state);
}
}
// Same as Cow but less annoying.
enum OwnedOrRef<T: 'static> {
Owned(T),
Ref(&'static T),
}
impl<T> Deref for OwnedOrRef<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
match *self {
OwnedOrRef::Owned(ref v) => v,
OwnedOrRef::Ref(v) => v,
}
}
}
/// Information that can be given to the Vulkan driver so that it can identify your application.
// TODO: better documentation for struct and methods
#[derive(Debug, Clone)]
pub struct ApplicationInfo<'a> {
/// Name of the application.
pub application_name: Option<Cow<'a, str>>,
/// An opaque number that contains the version number of the application.
pub application_version: Option<Version>,
/// Name of the engine used to power the application.
pub engine_name: Option<Cow<'a, str>>,
/// An opaque number that contains the version number of the engine.
pub engine_version: Option<Version>,
}
impl<'a> ApplicationInfo<'a> {
/// Builds an `ApplicationInfo` from the information gathered by Cargo.
///
/// # Panic
///
/// - Panics if the required environment variables are missing, which happens if the project
/// wasn't built by Cargo.
///
#[deprecated(note = "Please use the `app_info_from_cargo_toml!` macro instead")]
pub fn from_cargo_toml() -> ApplicationInfo<'a> {
let version = Version {
major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
};
let name = env!("CARGO_PKG_NAME");
ApplicationInfo {
application_name: Some(name.into()),
application_version: Some(version),
engine_name: None,
engine_version: None,
}
}
}
/// Builds an `ApplicationInfo` from the information gathered by Cargo.
///
/// # Panic
///
/// - Panics if the required environment variables are missing, which happens if the project
/// wasn't built by Cargo.
///
#[macro_export]
macro_rules! app_info_from_cargo_toml {
() => {{
let version = $crate::instance::Version {
major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
};
let name = env!("CARGO_PKG_NAME");
$crate::instance::ApplicationInfo {
application_name: Some(name.into()),
application_version: Some(version),
engine_name: None,
engine_version: None,
}
}};
}
impl<'a> Default for ApplicationInfo<'a> {
fn default() -> ApplicationInfo<'a> {
ApplicationInfo {
application_name: None,
application_version: None,
engine_name: None,
engine_version: None,
}
}
}
/// Error that can happen when creating an instance.
#[derive(Clone, Debug)]
pub enum InstanceCreationError {
/// Failed to load the Vulkan shared library.
LoadingError(LoadingError),
/// Not enough memory.
OomError(OomError),
/// Failed to initialize for an implementation-specific reason.
InitializationFailed,
/// One of the requested layers is missing.
LayerNotPresent,
/// One of the requested extensions is not supported by the implementation.
ExtensionNotPresent,
/// The version requested is not supported by the implementation.
IncompatibleDriver,
/// A restriction for an extension was not met.
ExtensionRestrictionNotMet(ExtensionRestrictionError),
}
impl error::Error for InstanceCreationError {
#[inline]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
InstanceCreationError::LoadingError(ref err) => Some(err),
InstanceCreationError::OomError(ref err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for InstanceCreationError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
InstanceCreationError::LoadingError(_) => {
write!(fmt, "failed to load the Vulkan shared library")
}
InstanceCreationError::OomError(_) => write!(fmt, "not enough memory available"),
InstanceCreationError::InitializationFailed => write!(fmt, "initialization failed"),
InstanceCreationError::LayerNotPresent => write!(fmt, "layer not present"),
InstanceCreationError::ExtensionNotPresent => write!(fmt, "extension not present"),
InstanceCreationError::IncompatibleDriver => write!(fmt, "incompatible driver"),
InstanceCreationError::ExtensionRestrictionNotMet(err) => err.fmt(fmt),
}
}
}
impl From<OomError> for InstanceCreationError {
#[inline]
fn from(err: OomError) -> InstanceCreationError {
InstanceCreationError::OomError(err)
}
}
impl From<LoadingError> for InstanceCreationError {
#[inline]
fn from(err: LoadingError) -> InstanceCreationError {
InstanceCreationError::LoadingError(err)
}
}
impl From<ExtensionRestrictionError> for InstanceCreationError {
#[inline]
fn from(err: ExtensionRestrictionError) -> Self {
Self::ExtensionRestrictionNotMet(err)
}
}
impl From<Error> for InstanceCreationError {
#[inline]
fn from(err: Error) -> InstanceCreationError {
match err {
err @ Error::OutOfHostMemory => InstanceCreationError::OomError(OomError::from(err)),
err @ Error::OutOfDeviceMemory => InstanceCreationError::OomError(OomError::from(err)),
Error::InitializationFailed => InstanceCreationError::InitializationFailed,
Error::LayerNotPresent => InstanceCreationError::LayerNotPresent,
Error::ExtensionNotPresent => InstanceCreationError::ExtensionNotPresent,
Error::IncompatibleDriver => InstanceCreationError::IncompatibleDriver,
_ => panic!("unexpected error: {:?}", err),
}
}
}
#[cfg(test)]
mod tests {
use crate::device::physical::PhysicalDevice;
#[test]
fn create_instance() {
let _ = instance!();
}
#[test]
fn queue_family_by_id() {
let instance = instance!();
let phys = match PhysicalDevice::enumerate(&instance).next() {
Some(p) => p,
None => return,
};
let queue_family = match phys.queue_families().next() {
Some(q) => q,
None => return,
};
let by_id = phys.queue_family_by_id(queue_family.id()).unwrap();
assert_eq!(by_id.id(), queue_family.id());
}
}

View File

@ -38,7 +38,7 @@ use std::os::raw::c_void;
use std::path::Path;
/// Implemented on objects that grant access to a Vulkan implementation.
pub unsafe trait Loader {
pub unsafe trait Loader: Send + Sync {
/// Calls the `vkGetInstanceProcAddr` function. The parameters are the same.
///
/// The returned function must stay valid for as long as `self` is alive.
@ -51,7 +51,7 @@ pub unsafe trait Loader {
unsafe impl<T> Loader for T
where
T: SafeDeref,
T: SafeDeref + Send + Sync,
T::Target: Loader,
{
#[inline]
@ -64,6 +64,13 @@ where
}
}
impl fmt::Debug for dyn Loader {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Ok(())
}
}
/// Implementation of `Loader` that loads Vulkan from a dynamic library.
pub struct DynamicLibraryLoader {
vk_lib: shared_library::dynamic_library::DynamicLibrary,
@ -112,6 +119,7 @@ unsafe impl Loader for DynamicLibraryLoader {
}
/// Wraps around a loader and contains function pointers.
#[derive(Debug)]
pub struct FunctionPointers<L> {
loader: L,
fns: EntryFunctions,
@ -218,17 +226,16 @@ macro_rules! statically_linked_vulkan_loader {
/// This function tries to auto-guess where to find the Vulkan implementation, and loads it in a
/// `lazy_static!`. The content of the lazy_static is then returned, or an error if we failed to
/// load Vulkan.
pub fn auto_loader(
) -> Result<&'static FunctionPointers<Box<dyn Loader + Send + Sync>>, LoadingError> {
pub fn auto_loader() -> Result<&'static FunctionPointers<Box<dyn Loader>>, LoadingError> {
#[cfg(target_os = "ios")]
#[allow(non_snake_case)]
fn def_loader_impl() -> Result<Box<Loader + Send + Sync>, LoadingError> {
fn def_loader_impl() -> Result<Box<Loader>, LoadingError> {
let loader = statically_linked_vulkan_loader!();
Ok(Box::new(loader))
}
#[cfg(not(target_os = "ios"))]
fn def_loader_impl() -> Result<Box<dyn Loader + Send + Sync>, LoadingError> {
fn def_loader_impl() -> Result<Box<dyn Loader>, LoadingError> {
#[cfg(windows)]
fn get_path() -> &'static Path {
Path::new("vulkan-1.dll")
@ -252,7 +259,7 @@ pub fn auto_loader(
}
lazy_static! {
static ref DEFAULT_LOADER: Result<FunctionPointers<Box<dyn Loader + Send + Sync>>, LoadingError> =
static ref DEFAULT_LOADER: Result<FunctionPointers<Box<dyn Loader>>, LoadingError> =
def_loader_impl().map(FunctionPointers::new);
}

View File

@ -18,7 +18,7 @@
//! use vulkano::instance::InstanceExtensions;
//! use vulkano::Version;
//!
//! let instance = match Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None) {
//! let instance = match Instance::new(Default::default()) {
//! Ok(i) => i,
//! Err(err) => panic!("Couldn't build instance: {:?}", err)
//! };
@ -33,7 +33,7 @@
//! # use vulkano::Version;
//! use vulkano::device::physical::PhysicalDevice;
//!
//! # let instance = Instance::new(None, Version::V1_1, &InstanceExtensions::none(), None).unwrap();
//! # let instance = Instance::new(Default::default()).unwrap();
//! for physical_device in PhysicalDevice::enumerate(&instance) {
//! println!("Available device: {}", physical_device.properties().device_name);
//! }
@ -52,20 +52,600 @@
//! `device` module for more info.
pub use self::extensions::InstanceExtensions;
pub use self::instance::ApplicationInfo;
pub use self::instance::Instance;
pub use self::instance::InstanceCreationError;
pub use self::layers::layers_list;
pub use self::layers::LayerProperties;
pub use self::layers::LayersListError;
pub use self::loader::LoadingError;
use crate::check_errors;
use crate::device::physical::{init_physical_devices, PhysicalDeviceInfo};
pub use crate::extensions::{
ExtensionRestriction, ExtensionRestrictionError, SupportedExtensionsError,
};
use crate::fns::InstanceFunctions;
use crate::instance::loader::FunctionPointers;
use crate::instance::loader::Loader;
pub use crate::version::Version;
use crate::Error;
use crate::OomError;
use crate::VulkanObject;
use smallvec::SmallVec;
use std::error;
use std::ffi::CString;
use std::fmt;
use std::hash::Hash;
use std::hash::Hasher;
use std::mem::MaybeUninit;
use std::ops::Deref;
use std::ptr;
use std::sync::Arc;
pub mod debug;
pub(crate) mod extensions;
mod instance;
mod layers;
pub mod loader;
/// An instance of a Vulkan context. This is the main object that should be created by an
/// application before everything else.
///
/// # Application and engine info
///
/// When you create an instance, you have the possibility to set information about your application
/// and its engine.
///
/// Providing this information allows for example the driver to let the user configure the driver's
/// behavior for your application alone through a control panel.
///
/// ```no_run
/// # #[macro_use] extern crate vulkano;
/// # fn main() {
/// use vulkano::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
/// use vulkano::Version;
///
/// let _instance = Instance::new(InstanceCreateInfo::application_from_cargo_toml()).unwrap();
/// # }
/// ```
///
/// # API versions
///
/// Both an `Instance` and a [`Device`](crate::device::Device) have a highest version of the Vulkan
/// API that they support. This places a limit on what Vulkan functions and features are available
/// to use when used on a particular instance or device. It is possible for the instance and the
/// device to support different versions. The supported version for an instance can be queried
/// before creation with
/// [`FunctionPointers::api_version`](crate::instance::loader::FunctionPointers::api_version),
/// while for a device it can be retrieved with
/// [`PhysicalDevice::api_version`](crate::device::physical::PhysicalDevice::api_version).
///
/// When creating an `Instance`, you have to specify a maximum API version that you will use.
/// This restricts the API version that is available for the instance and any devices created from
/// it. For example, if both instance and device potentially support Vulkan 1.2, but you specify
/// 1.1 as the maximum API version when creating the `Instance`, then you can only use Vulkan 1.1
/// functions, even though they could theoretically support a higher version. You can think of it
/// as a promise never to use any functionality from a higher version.
///
/// The maximum API version is not a _minimum_, so it is possible to set it to a higher version than
/// what the instance or device inherently support. The final API version that you are able to use
/// on an instance or device is the lower of the supported API version and the chosen maximum API
/// version of the `Instance`.
///
/// Due to a quirk in how the Vulkan 1.0 specification was written, if the instance only
/// supports Vulkan 1.0, then it is not possible to specify a maximum API version higher than 1.0.
/// Trying to create an `Instance` will return an `IncompatibleDriver` error. Consequently, it is
/// not possible to use a higher device API version with an instance that only supports 1.0.
///
/// # Extensions
///
/// When creating an `Instance`, you must provide 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, InstanceCreateInfo, InstanceExtensions};
/// use vulkano::Version;
///
/// let extensions = InstanceExtensions {
/// khr_surface: true,
/// khr_android_surface: true,
/// .. InstanceExtensions::none()
/// };
///
/// let instance = match Instance::new(InstanceCreateInfo {
/// enabled_extensions: extensions,
/// ..Default::default()
/// }) {
/// Ok(i) => i,
/// Err(err) => panic!("Couldn't build instance: {:?}", err)
/// };
/// ```
///
/// # Layers
///
/// When creating an `Instance`, you have the possibility to pass a list of **layers** that will
/// be activated on the newly-created instance. The list of available layers can be retrieved by
/// calling [the `layers_list` function](crate::instance::layers_list).
///
/// A layer is a component that will hook and potentially modify the Vulkan function calls.
/// For example, activating a layer could add a frames-per-second counter on the screen, or it
/// could send information to a debugger that will debug your application.
///
/// > **Note**: From an application's point of view, layers "just exist". In practice, on Windows
/// > and Linux, layers can be installed by third party installers or by package managers and can
/// > also be activated by setting the value of the `VK_INSTANCE_LAYERS` environment variable
/// > before starting the program. See the documentation of the official Vulkan loader for these
/// > platforms.
///
/// > **Note**: In practice, the most common use of layers right now is for debugging purposes.
/// > To do so, you are encouraged to set the `VK_INSTANCE_LAYERS` environment variable on Windows
/// > or Linux instead of modifying the source code of your program. For example:
/// > `export VK_INSTANCE_LAYERS=VK_LAYER_LUNARG_api_dump` on Linux if you installed the Vulkan SDK
/// > will print the list of raw Vulkan function calls.
///
/// ## Example
///
/// ```
/// # use std::sync::Arc;
/// # use std::error::Error;
/// # use vulkano::instance;
/// # use vulkano::instance::Instance;
/// # use vulkano::instance::InstanceCreateInfo;
/// # use vulkano::instance::InstanceExtensions;
/// # use vulkano::Version;
/// # fn test() -> Result<Arc<Instance>, Box<dyn Error>> {
/// // For the sake of the example, we activate all the layers that
/// // contain the word "foo" in their description.
/// let layers: Vec<_> = instance::layers_list()?
/// .filter(|l| l.description().contains("foo"))
/// .collect();
///
/// let instance = Instance::new(InstanceCreateInfo {
/// enabled_layers: layers.iter().map(|l| l.name().to_owned()).collect(),
/// ..Default::default()
/// })?;
/// # Ok(instance)
/// # }
/// ```
// TODO: mention that extensions must be supported by layers as well
#[derive(Debug)]
pub struct Instance {
handle: ash::vk::Instance,
fns: InstanceFunctions,
pub(crate) physical_device_infos: Vec<PhysicalDeviceInfo>,
api_version: Version,
enabled_extensions: InstanceExtensions,
enabled_layers: Vec<String>,
function_pointers: OwnedOrRef<FunctionPointers<Box<dyn Loader>>>,
max_api_version: Version,
}
// TODO: fix the underlying cause instead
impl ::std::panic::UnwindSafe for Instance {}
impl ::std::panic::RefUnwindSafe for Instance {}
impl Instance {
/// Creates a new `Instance`.
///
/// # Panics
///
/// - Panics if any version numbers in `create_info` contain a field too large to be converted
/// into a Vulkan version number.
/// - Panics if `create_info.max_api_version` is not at least `V1_0`.
pub fn new(create_info: InstanceCreateInfo) -> Result<Arc<Instance>, InstanceCreationError> {
let InstanceCreateInfo {
application_name,
application_version,
enabled_extensions,
enabled_layers,
engine_name,
engine_version,
function_pointers,
max_api_version,
_ne: _,
} = create_info;
let function_pointers = if let Some(function_pointers) = function_pointers {
OwnedOrRef::Owned(function_pointers)
} else {
OwnedOrRef::Ref(loader::auto_loader()?)
};
let (api_version, max_api_version) = {
let api_version = function_pointers.api_version()?;
let max_api_version = if let Some(max_api_version) = max_api_version {
max_api_version
} else if api_version < Version::V1_1 {
api_version
} else {
Version::V1_2 // TODO: Can this be extracted from vk.xml somehow?
};
(std::cmp::min(max_api_version, api_version), max_api_version)
};
// VUID-VkApplicationInfo-apiVersion-04010
assert!(max_api_version >= Version::V1_0);
// Check if the extensions are correct
enabled_extensions.check_requirements(
&InstanceExtensions::supported_by_core_with_loader(&function_pointers)?,
api_version,
)?;
// FIXME: check whether each layer is supported
let enabled_layers_cstr: Vec<CString> = enabled_layers
.iter()
.map(|name| CString::new(name.clone()).unwrap())
.collect();
let enabled_layers_ptrs = enabled_layers_cstr
.iter()
.map(|layer| layer.as_ptr())
.collect::<SmallVec<[_; 2]>>();
let enabled_extensions_cstr: Vec<CString> = (&enabled_extensions).into();
let enabled_extensions_ptrs = enabled_extensions_cstr
.iter()
.map(|extension| extension.as_ptr())
.collect::<SmallVec<[_; 2]>>();
let application_name_cstr = application_name.map(|name| CString::new(name).unwrap());
let engine_name_cstr = engine_name.map(|name| CString::new(name).unwrap());
let application_info = ash::vk::ApplicationInfo {
p_application_name: application_name_cstr
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or(ptr::null()),
application_version: application_version
.try_into()
.expect("Version out of range"),
p_engine_name: engine_name_cstr
.as_ref()
.map(|s| s.as_ptr())
.unwrap_or(ptr::null()),
engine_version: engine_version.try_into().expect("Version out of range"),
api_version: max_api_version.try_into().expect("Version out of range"),
..Default::default()
};
let create_info = ash::vk::InstanceCreateInfo {
flags: ash::vk::InstanceCreateFlags::empty(),
p_application_info: &application_info,
enabled_layer_count: enabled_layers_ptrs.len() as u32,
pp_enabled_layer_names: enabled_layers_ptrs.as_ptr(),
enabled_extension_count: enabled_extensions_ptrs.len() as u32,
pp_enabled_extension_names: enabled_extensions_ptrs.as_ptr(),
..Default::default()
};
// Creating the Vulkan instance.
let handle = unsafe {
let mut output = MaybeUninit::uninit();
let fns = function_pointers.fns();
check_errors(
fns.v1_0
.create_instance(&create_info, ptr::null(), output.as_mut_ptr()),
)?;
output.assume_init()
};
// Loading the function pointers of the newly-created instance.
let fns = {
InstanceFunctions::load(|name| {
function_pointers.get_instance_proc_addr(handle, name.as_ptr())
})
};
let mut instance = Instance {
handle,
fns,
physical_device_infos: Vec::new(),
api_version,
enabled_extensions,
enabled_layers,
function_pointers,
max_api_version,
};
// Enumerating all physical devices.
instance.physical_device_infos = init_physical_devices(&instance)?;
Ok(Arc::new(instance))
}
/// Returns the Vulkan version supported by the instance.
///
/// This is the lower of the
/// [driver's supported version](crate::instance::loader::FunctionPointers::api_version) and
/// [`max_api_version`](Instance::max_api_version).
#[inline]
pub fn api_version(&self) -> Version {
self.api_version
}
/// Returns the maximum Vulkan version that was specified when creating the instance.
#[inline]
pub fn max_api_version(&self) -> Version {
self.max_api_version
}
/// Grants access to the Vulkan functions of the instance.
#[inline]
pub fn fns(&self) -> &InstanceFunctions {
&self.fns
}
/// Returns the extensions that have been enabled on the instance.
#[inline]
pub fn enabled_extensions(&self) -> &InstanceExtensions {
&self.enabled_extensions
}
/// Returns the layers that have been enabled on the instance.
#[inline]
pub fn enabled_layers(&self) -> &[String] {
&self.enabled_layers
}
}
impl Drop for Instance {
#[inline]
fn drop(&mut self) {
unsafe {
self.fns.v1_0.destroy_instance(self.handle, ptr::null());
}
}
}
unsafe impl VulkanObject for Instance {
type Object = ash::vk::Instance;
#[inline]
fn internal_object(&self) -> ash::vk::Instance {
self.handle
}
}
impl PartialEq for Instance {
#[inline]
fn eq(&self, other: &Self) -> bool {
self.handle == other.handle
}
}
impl Eq for Instance {}
impl Hash for Instance {
#[inline]
fn hash<H: Hasher>(&self, state: &mut H) {
self.handle.hash(state);
}
}
/// Parameters to create a new `Instance`.
#[derive(Debug)]
pub struct InstanceCreateInfo {
/// A string of your choice stating the name of your application.
///
/// The default value is `None`.
pub application_name: Option<String>,
/// A version number of your choice specifying the version of your application.
///
/// The default value is zero.
pub application_version: Version,
/// The extensions to enable on the instance.
///
/// The default value is [`InstanceExtensions::none()`].
pub enabled_extensions: InstanceExtensions,
/// The layers to enable on the instance.
///
/// The default value is empty.
pub enabled_layers: Vec<String>,
/// A string of your choice stating the name of the engine used to power the application.
pub engine_name: Option<String>,
/// A version number of your choice specifying the version of the engine used to power the
/// application.
///
/// The default value is zero.
pub engine_version: Version,
/// Function pointers loaded from a custom loader.
///
/// You can use this if you want to load the Vulkan API explicitly, rather than using Vulkano's
/// default.
pub function_pointers: Option<FunctionPointers<Box<dyn Loader>>>,
/// The highest Vulkan API version that the application will use with the instance.
///
/// Usually, you will want to leave this at the default.
///
/// The default value is the highest version currently supported by Vulkano, but if the
/// supported instance version is 1.0, then it will be 1.0.
pub max_api_version: Option<Version>,
pub _ne: crate::NonExhaustive,
}
impl Default for InstanceCreateInfo {
#[inline]
fn default() -> Self {
Self {
application_name: None,
application_version: Version::major_minor(0, 0),
enabled_extensions: InstanceExtensions::none(),
enabled_layers: Vec::new(),
engine_name: None,
engine_version: Version::major_minor(0, 0),
function_pointers: None,
max_api_version: None,
_ne: crate::NonExhaustive(()),
}
}
}
impl InstanceCreateInfo {
/// Returns an `InstanceCreateInfo` with the `application_name` and `application_version` set
/// from information in your crate's Cargo.toml file.
///
/// # Panics
///
/// - Panics if the required environment variables are missing, which happens if the project
/// wasn't built by Cargo.
#[inline]
pub fn application_from_cargo_toml() -> Self {
Self {
application_name: Some(env!("CARGO_PKG_NAME").to_owned()),
application_version: Version {
major: env!("CARGO_PKG_VERSION_MAJOR").parse().unwrap(),
minor: env!("CARGO_PKG_VERSION_MINOR").parse().unwrap(),
patch: env!("CARGO_PKG_VERSION_PATCH").parse().unwrap(),
},
..Default::default()
}
}
}
/// Error that can happen when creating an instance.
#[derive(Clone, Debug)]
pub enum InstanceCreationError {
/// Failed to load the Vulkan shared library.
LoadingError(LoadingError),
/// Not enough memory.
OomError(OomError),
/// Failed to initialize for an implementation-specific reason.
InitializationFailed,
/// One of the requested layers is missing.
LayerNotPresent,
/// One of the requested extensions is not supported by the implementation.
ExtensionNotPresent,
/// The version requested is not supported by the implementation.
IncompatibleDriver,
/// A restriction for an extension was not met.
ExtensionRestrictionNotMet(ExtensionRestrictionError),
}
impl error::Error for InstanceCreationError {
#[inline]
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match *self {
InstanceCreationError::LoadingError(ref err) => Some(err),
InstanceCreationError::OomError(ref err) => Some(err),
_ => None,
}
}
}
impl fmt::Display for InstanceCreationError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
InstanceCreationError::LoadingError(_) => {
write!(fmt, "failed to load the Vulkan shared library")
}
InstanceCreationError::OomError(_) => write!(fmt, "not enough memory available"),
InstanceCreationError::InitializationFailed => write!(fmt, "initialization failed"),
InstanceCreationError::LayerNotPresent => write!(fmt, "layer not present"),
InstanceCreationError::ExtensionNotPresent => write!(fmt, "extension not present"),
InstanceCreationError::IncompatibleDriver => write!(fmt, "incompatible driver"),
InstanceCreationError::ExtensionRestrictionNotMet(err) => err.fmt(fmt),
}
}
}
impl From<OomError> for InstanceCreationError {
#[inline]
fn from(err: OomError) -> InstanceCreationError {
InstanceCreationError::OomError(err)
}
}
impl From<LoadingError> for InstanceCreationError {
#[inline]
fn from(err: LoadingError) -> InstanceCreationError {
InstanceCreationError::LoadingError(err)
}
}
impl From<ExtensionRestrictionError> for InstanceCreationError {
#[inline]
fn from(err: ExtensionRestrictionError) -> Self {
Self::ExtensionRestrictionNotMet(err)
}
}
impl From<Error> for InstanceCreationError {
#[inline]
fn from(err: Error) -> InstanceCreationError {
match err {
err @ Error::OutOfHostMemory => InstanceCreationError::OomError(OomError::from(err)),
err @ Error::OutOfDeviceMemory => InstanceCreationError::OomError(OomError::from(err)),
Error::InitializationFailed => InstanceCreationError::InitializationFailed,
Error::LayerNotPresent => InstanceCreationError::LayerNotPresent,
Error::ExtensionNotPresent => InstanceCreationError::ExtensionNotPresent,
Error::IncompatibleDriver => InstanceCreationError::IncompatibleDriver,
_ => panic!("unexpected error: {:?}", err),
}
}
}
// Same as Cow but less annoying.
#[derive(Debug)]
enum OwnedOrRef<T: 'static> {
Owned(T),
Ref(&'static T),
}
impl<T> Deref for OwnedOrRef<T> {
type Target = T;
#[inline]
fn deref(&self) -> &T {
match *self {
OwnedOrRef::Owned(ref v) => v,
OwnedOrRef::Ref(v) => v,
}
}
}
#[cfg(test)]
mod tests {
use crate::device::physical::PhysicalDevice;
#[test]
fn create_instance() {
let _ = instance!();
}
#[test]
fn queue_family_by_id() {
let instance = instance!();
let phys = match PhysicalDevice::enumerate(&instance).next() {
Some(p) => p,
None => return,
};
let queue_family = match phys.queue_families().next() {
Some(q) => q,
None => return,
};
let by_id = phys.queue_family_by_id(queue_family.id()).unwrap();
assert_eq!(by_id.id(), queue_family.id());
}
}

View File

@ -55,8 +55,7 @@
//!
//! ```no_run
//! use std::ptr;
//! use vulkano::instance::Instance;
//! use vulkano::instance::InstanceExtensions;
//! use vulkano::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
//! use vulkano::swapchain::Surface;
//! use vulkano::Version;
//!
@ -67,7 +66,10 @@
//! .. InstanceExtensions::none()
//! };
//!
//! match Instance::new(None, Version::V1_1, &extensions, None) {
//! match Instance::new(InstanceCreateInfo {
//! enabled_extensions: extensions,
//! ..Default::default()
//! }) {
//! Ok(i) => i,
//! Err(err) => panic!("Couldn't build instance: {:?}", err)
//! }

View File

@ -344,24 +344,21 @@ mod tests {
))]
fn semaphore_export() {
use crate::device::physical::PhysicalDevice;
use crate::device::{Device, DeviceExtensions};
use crate::instance::{Instance, InstanceExtensions};
use crate::Version;
use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use crate::instance::{Instance, InstanceCreateInfo, InstanceExtensions};
let supported_ext = InstanceExtensions::supported_by_core().unwrap();
if supported_ext.khr_get_display_properties2
&& supported_ext.khr_external_semaphore_capabilities
{
let instance = Instance::new(
None,
Version::V1_1,
&InstanceExtensions {
let instance = Instance::new(InstanceCreateInfo {
enabled_extensions: InstanceExtensions {
khr_get_physical_device_properties2: true,
khr_external_semaphore_capabilities: true,
..InstanceExtensions::none()
},
None,
)
..Default::default()
})
.unwrap();
let physical = PhysicalDevice::enumerate(&instance).next().unwrap();
@ -375,9 +372,11 @@ mod tests {
};
let (device, _) = Device::new(
physical,
physical.supported_features(),
&device_ext,
[(queue_family, 0.5)].iter().cloned(),
DeviceCreateInfo {
enabled_extensions: device_ext,
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
..Default::default()
},
)
.unwrap();

View File

@ -12,15 +12,9 @@
/// Creates an instance or returns if initialization fails.
macro_rules! instance {
() => {{
use crate::instance;
use crate::Version;
use crate::instance::Instance;
match instance::Instance::new(
None,
Version::V1_1,
&instance::InstanceExtensions::none(),
None,
) {
match Instance::new(Default::default()) {
Ok(i) => i,
Err(_) => return,
}
@ -31,8 +25,7 @@ macro_rules! instance {
macro_rules! gfx_dev_and_queue {
($($feature:ident),*) => ({
use crate::device::physical::PhysicalDevice;
use crate::device::Device;
use crate::device::DeviceExtensions;
use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
use crate::device::Features;
let instance = instance!();
@ -42,7 +35,7 @@ macro_rules! gfx_dev_and_queue {
None => return
};
let queue = match physical.queue_families().find(|q| q.supports_graphics()) {
let queue_family = match physical.queue_families().find(|q| q.supports_graphics()) {
Some(q) => q,
None => return
};
@ -61,9 +54,15 @@ macro_rules! gfx_dev_and_queue {
return;
}
let (device, mut queues) = match Device::new(physical, &features,
&extensions, [(queue, 0.5)].iter().cloned())
{
let (device, mut queues) = match Device::new(
physical,
DeviceCreateInfo {
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
enabled_extensions: extensions,
enabled_features: features,
..Default::default()
}
) {
Ok(r) => r,
Err(_) => return
};

View File

@ -9,7 +9,7 @@
// The `Version` object is reexported from the `instance` module.
use std::fmt;
use std::{fmt, num::ParseIntError, str::FromStr};
/// Represents an API version of Vulkan.
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
@ -73,6 +73,23 @@ impl TryFrom<Version> for u32 {
}
}
impl FromStr for Version {
type Err = ParseIntError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut iter = s.splitn(3, '.');
let major: u32 = iter.next().unwrap().parse()?;
let minor: u32 = iter.next().map_or(Ok(0), |n| n.parse())?;
let patch: u32 = iter.next().map_or(Ok(0), |n| n.parse())?;
Ok(Version {
major,
minor,
patch,
})
}
}
impl fmt::Debug for Version {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)