mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-25 16:25:31 +00:00
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:
parent
33aa520706
commit
8775777f47
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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())
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)*
|
||||
}
|
||||
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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>,
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
},
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
//! }
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user