mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 06:45:23 +00:00
Make PhysicalDevice
an independent object (#1967)
* Better validation and errors * Small fix * Make `PhysicalDevice` an independent object Co-authored-by: Austin Johnson <me@austinj.work>
This commit is contained in:
parent
b06b29afd2
commit
4abc27b9e5
@ -18,8 +18,7 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -45,14 +44,17 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
// The Vulkan specs guarantee that a compliant implementation must provide at least one queue
|
// The Vulkan specs guarantee that a compliant implementation must provide at least one queue
|
||||||
// that supports compute operations.
|
// that supports compute operations.
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -75,7 +77,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -170,7 +175,7 @@ fn main() {
|
|||||||
// In order to execute our operation, we have to build a command buffer.
|
// In order to execute our operation, we have to build a command buffer.
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -30,8 +30,7 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -88,12 +87,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -115,7 +120,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -124,11 +132,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -320,7 +330,7 @@ fn main() {
|
|||||||
let buffer = buffer_pool.chunk(data.to_vec()).unwrap();
|
let buffer = buffer_pool.chunk(data.to_vec()).unwrap();
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -14,8 +14,7 @@ use vulkano::{
|
|||||||
RenderPassBeginInfo, SubpassContents,
|
RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageUsage, SwapchainImage},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
@ -59,12 +58,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -86,7 +91,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -94,11 +102,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -203,7 +213,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -10,8 +10,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{ImageDimensions, ImmutableImage, MipmapsCount},
|
image::{ImageDimensions, ImmutableImage, MipmapsCount},
|
||||||
@ -144,12 +143,13 @@ fn main() {
|
|||||||
let device_extensions = DeviceExtensions {
|
let device_extensions = DeviceExtensions {
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
p.queue_families()
|
(!p.queue_family_properties().is_empty())
|
||||||
.next()
|
.then_some((p, 0))
|
||||||
.map(|q| (p, q))
|
|
||||||
.expect("couldn't find a queue family")
|
.expect("couldn't find a queue family")
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
@ -166,7 +166,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -138,7 +138,7 @@ impl AmbientLightingSystem {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -152,7 +152,7 @@ impl DirectionalLightingSystem {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -165,7 +165,7 @@ impl PointLightingSystem {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -305,7 +305,7 @@ impl FrameSystem {
|
|||||||
// Start the command buffer builder that will be filled throughout the frame handling.
|
// Start the command buffer builder that will be filled throughout the frame handling.
|
||||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -32,8 +32,7 @@ use crate::{
|
|||||||
use cgmath::{Matrix4, SquareMatrix, Vector3};
|
use cgmath::{Matrix4, SquareMatrix, Vector3};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageUsage},
|
image::{view::ImageView, ImageUsage},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
@ -78,12 +77,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -105,7 +110,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -113,11 +121,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, mut images) = {
|
let (mut swapchain, mut images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
|
@ -91,7 +91,7 @@ impl TriangleDrawSystem {
|
|||||||
pub fn draw(&self, viewport_dimensions: [u32; 2]) -> SecondaryAutoCommandBuffer {
|
pub fn draw(&self, viewport_dimensions: [u32; 2]) -> SecondaryAutoCommandBuffer {
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -22,8 +22,7 @@ use vulkano::{
|
|||||||
layout::DescriptorType, DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet,
|
layout::DescriptorType, DescriptorSet, PersistentDescriptorSet, WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -47,12 +46,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -74,7 +76,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -187,7 +192,7 @@ fn main() {
|
|||||||
// Build the command buffer, using different offsets for each call.
|
// Build the command buffer, using different offsets for each call.
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -20,8 +20,7 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, CopyImageToBufferInfo},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage, CopyImageToBufferInfo},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, ImageDimensions, StorageImage},
|
image::{view::ImageView, ImageDimensions, StorageImage},
|
||||||
@ -53,12 +52,15 @@ fn main() {
|
|||||||
let device_extensions = DeviceExtensions {
|
let device_extensions = DeviceExtensions {
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -80,7 +82,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -152,7 +157,7 @@ fn main() {
|
|||||||
// In this case we can find appropriate value in this table: https://vulkan.gpuinfo.org/
|
// In this case we can find appropriate value in this table: https://vulkan.gpuinfo.org/
|
||||||
// or just use fallback constant for simplicity, but failure to set proper
|
// or just use fallback constant for simplicity, but failure to set proper
|
||||||
// local size can lead to significant performance penalty.
|
// local size can lead to significant performance penalty.
|
||||||
let (local_size_x, local_size_y) = match physical_device.properties().subgroup_size {
|
let (local_size_x, local_size_y) = match device.physical_device().properties().subgroup_size {
|
||||||
Some(subgroup_size) => {
|
Some(subgroup_size) => {
|
||||||
println!("Subgroup size is {}", subgroup_size);
|
println!("Subgroup size is {}", subgroup_size);
|
||||||
|
|
||||||
@ -196,7 +201,7 @@ fn main() {
|
|||||||
array_layers: 1,
|
array_layers: 1,
|
||||||
},
|
},
|
||||||
Format::R8G8B8A8_UNORM,
|
Format::R8G8B8A8_UNORM,
|
||||||
Some(queue.family()),
|
Some(queue.queue_family_index()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let view = ImageView::new_default(image.clone()).unwrap();
|
let view = ImageView::new_default(image.clone()).unwrap();
|
||||||
@ -219,7 +224,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -20,8 +20,8 @@ mod linux {
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Queue,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, ImageCreateFlags, ImageUsage, StorageImage, SwapchainImage},
|
image::{view::ImageView, ImageCreateFlags, ImageUsage, StorageImage, SwapchainImage},
|
||||||
@ -108,7 +108,7 @@ mod linux {
|
|||||||
mutable_format: true,
|
mutable_format: true,
|
||||||
..ImageCreateFlags::empty()
|
..ImageCreateFlags::empty()
|
||||||
},
|
},
|
||||||
[queue.family()],
|
[queue.queue_family_index()],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ mod linux {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -440,14 +440,19 @@ mod linux {
|
|||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| {
|
.iter()
|
||||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics
|
||||||
|
&& p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
})
|
})
|
||||||
.map(|q| (p, q))
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.filter(|(p, _)| p.properties().driver_uuid.unwrap() == display.driver_uuid().unwrap())
|
.filter(|(p, _)| p.properties().driver_uuid.unwrap() == display.driver_uuid().unwrap())
|
||||||
.filter(|(p, _)| {
|
.filter(|(p, _)| {
|
||||||
@ -476,7 +481,10 @@ mod linux {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -485,11 +493,13 @@ mod linux {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (swapchain, images) = {
|
let (swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
|
@ -18,8 +18,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -78,12 +77,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -105,7 +110,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -113,11 +121,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -216,7 +226,7 @@ fn main() {
|
|||||||
device.clone(),
|
device.clone(),
|
||||||
dimensions,
|
dimensions,
|
||||||
Format::R8G8B8A8_UNORM,
|
Format::R8G8B8A8_UNORM,
|
||||||
[queue.family()],
|
[queue.queue_family_index()],
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -233,7 +243,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -396,7 +406,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -76,12 +75,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -103,7 +108,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -111,11 +119,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -313,7 +323,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -25,8 +25,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -82,12 +81,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -109,7 +114,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -117,11 +125,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -324,7 +334,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -34,8 +34,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -96,12 +95,18 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -123,7 +128,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -132,11 +140,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -389,7 +399,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -20,8 +20,7 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -94,12 +93,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -121,7 +126,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -130,11 +138,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -361,7 +371,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -118,7 +118,7 @@ impl FractalComputePipeline {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
self.queue.device().clone(),
|
self.queue.device().clone(),
|
||||||
self.queue.family(),
|
self.queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -155,7 +155,7 @@ impl PixelsDrawPipeline {
|
|||||||
) -> SecondaryAutoCommandBuffer {
|
) -> SecondaryAutoCommandBuffer {
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -79,7 +79,7 @@ impl RenderPassPlaceOverFrame {
|
|||||||
// Create primary command buffer builder
|
// Create primary command buffer builder
|
||||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -73,8 +73,7 @@ use vulkano::{
|
|||||||
RenderPassBeginInfo, SubpassContents,
|
RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, AttachmentImage, ImageDimensions, SampleCount, StorageImage},
|
image::{view::ImageView, AttachmentImage, ImageDimensions, SampleCount, StorageImage},
|
||||||
@ -112,12 +111,15 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.graphics)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -139,7 +141,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -170,7 +175,7 @@ fn main() {
|
|||||||
array_layers: 1,
|
array_layers: 1,
|
||||||
},
|
},
|
||||||
Format::R8G8B8A8_UNORM,
|
Format::R8G8B8A8_UNORM,
|
||||||
Some(queue.family()),
|
Some(queue.queue_family_index()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let view = ImageView::new_default(image.clone()).unwrap();
|
let view = ImageView::new_default(image.clone()).unwrap();
|
||||||
@ -322,7 +327,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -24,8 +24,7 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -94,14 +93,19 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| {
|
.iter()
|
||||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics
|
||||||
|
&& p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
})
|
})
|
||||||
.map(|q| (p, q))
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -123,19 +127,21 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
(
|
let surface_capabilities = device
|
||||||
device,
|
.physical_device()
|
||||||
queues.next().unwrap(),
|
.surface_capabilities(&surface, Default::default())
|
||||||
physical_device
|
.unwrap();
|
||||||
.surface_capabilities(&surface, Default::default())
|
|
||||||
.unwrap(),
|
(device, queues.next().unwrap(), surface_capabilities)
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// The swapchain and framebuffer images for this perticular window
|
// The swapchain and framebuffer images for this perticular window
|
||||||
@ -410,7 +416,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -112,7 +112,7 @@ impl GameOfLifeComputePipeline {
|
|||||||
) -> Box<dyn GpuFuture> {
|
) -> Box<dyn GpuFuture> {
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
self.compute_queue.device().clone(),
|
self.compute_queue.device().clone(),
|
||||||
self.compute_queue.family(),
|
self.compute_queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -155,7 +155,7 @@ impl PixelsDrawPipeline {
|
|||||||
) -> SecondaryAutoCommandBuffer {
|
) -> SecondaryAutoCommandBuffer {
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
CommandBufferInheritanceInfo {
|
CommandBufferInheritanceInfo {
|
||||||
render_pass: Some(self.subpass.clone().into()),
|
render_pass: Some(self.subpass.clone().into()),
|
||||||
|
@ -79,7 +79,7 @@ impl RenderPassPlaceOverFrame {
|
|||||||
// Create primary command buffer builder
|
// Create primary command buffer builder
|
||||||
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
let mut command_buffer_builder = AutoCommandBufferBuilder::primary(
|
||||||
self.gfx_queue.device().clone(),
|
self.gfx_queue.device().clone(),
|
||||||
self.gfx_queue.family(),
|
self.gfx_queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -22,8 +22,8 @@ use vulkano::{
|
|||||||
RenderPassBeginInfo, SubpassContents,
|
RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -73,14 +73,14 @@ fn main() {
|
|||||||
multiview: true,
|
multiview: true,
|
||||||
..Features::empty()
|
..Features::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance.enumerate_physical_devices().unwrap()
|
||||||
.filter(|&p| {
|
.filter(|p| {
|
||||||
p.supported_extensions().contains(&device_extensions)
|
p.supported_extensions().contains(&device_extensions)
|
||||||
})
|
})
|
||||||
.filter(|&p| {
|
.filter(|p| {
|
||||||
p.supported_features().contains(&features)
|
p.supported_features().contains(&features)
|
||||||
})
|
})
|
||||||
.filter(|&p| {
|
.filter(|p| {
|
||||||
// This example renders to two layers of the framebuffer using the multiview
|
// This example renders to two layers of the framebuffer using the multiview
|
||||||
// extension so we check that at least two views are supported by the device.
|
// extension so we check that at least two views are supported by the device.
|
||||||
// Not checking this on a device that doesn't support two views
|
// Not checking this on a device that doesn't support two views
|
||||||
@ -90,9 +90,10 @@ fn main() {
|
|||||||
p.properties().max_multiview_view_count.unwrap_or(0) >= 2
|
p.properties().max_multiview_view_count.unwrap_or(0) >= 2
|
||||||
})
|
})
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.graphics)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -117,7 +118,10 @@ fn main() {
|
|||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
enabled_features: features,
|
enabled_features: features,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -139,7 +143,7 @@ fn main() {
|
|||||||
..ImageUsage::empty()
|
..ImageUsage::empty()
|
||||||
},
|
},
|
||||||
ImageCreateFlags::empty(),
|
ImageCreateFlags::empty(),
|
||||||
Some(queue_family),
|
Some(queue.queue_family_index()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
@ -291,7 +295,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue_family,
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -19,8 +19,8 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, DeviceOwned,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, DeviceOwned, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
@ -73,12 +73,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -100,7 +106,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -108,11 +117,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -367,7 +378,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -33,8 +33,7 @@ use std::{
|
|||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{cache::PipelineCache, ComputePipeline},
|
pipeline::{cache::PipelineCache, ComputePipeline},
|
||||||
@ -59,12 +58,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -87,7 +89,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -42,12 +41,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -69,7 +71,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -155,7 +160,7 @@ fn main() {
|
|||||||
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders::shaders!` macro.
|
// So be careful to only pass an instance of the struct generated by the `vulkano_shaders::shaders!` macro.
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::WriteDescriptorSet,
|
descriptor_set::WriteDescriptorSet,
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -74,12 +73,18 @@ fn main() {
|
|||||||
khr_push_descriptor: true,
|
khr_push_descriptor: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -101,7 +106,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -109,11 +117,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -309,7 +319,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -27,8 +27,7 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -89,12 +88,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -116,7 +121,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -124,11 +132,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -298,7 +308,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -21,8 +21,8 @@ use vulkano::{
|
|||||||
PersistentDescriptorSet, WriteDescriptorSet,
|
PersistentDescriptorSet, WriteDescriptorSet,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -81,12 +81,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -115,7 +121,10 @@ fn main() {
|
|||||||
descriptor_binding_variable_descriptor_count: true,
|
descriptor_binding_variable_descriptor_count: true,
|
||||||
..Features::empty()
|
..Features::empty()
|
||||||
},
|
},
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -123,11 +132,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -446,7 +457,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -42,12 +41,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -69,7 +71,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -134,7 +139,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -41,12 +40,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -68,7 +70,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -138,7 +143,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -33,8 +33,8 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Queue,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Queue, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -58,12 +58,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -85,7 +88,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -198,7 +204,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
queue.device().clone(),
|
queue.device().clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -23,8 +23,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageUsage},
|
image::{view::ImageView, ImageUsage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -82,12 +81,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -108,7 +113,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -116,12 +124,14 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (swapchain, images) = {
|
let (swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -348,14 +358,14 @@ fn main() {
|
|||||||
vertex_buffer: true,
|
vertex_buffer: true,
|
||||||
..BufferUsage::empty()
|
..BufferUsage::empty()
|
||||||
}, // Specify use as a storage buffer, vertex buffer, and transfer destination.
|
}, // Specify use as a storage buffer, vertex buffer, and transfer destination.
|
||||||
device.active_queue_families(),
|
device.active_queue_family_indices().iter().copied(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Create one-time command to copy between the buffers.
|
// Create one-time command to copy between the buffers.
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -486,7 +496,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -14,8 +14,7 @@ use vulkano::{
|
|||||||
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
command_buffer::{AutoCommandBufferBuilder, CommandBufferUsage},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
instance::{Instance, InstanceCreateInfo},
|
instance::{Instance, InstanceCreateInfo},
|
||||||
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
pipeline::{ComputePipeline, Pipeline, PipelineBindPoint},
|
||||||
@ -39,12 +38,15 @@ fn main() {
|
|||||||
khr_storage_buffer_storage_class: true,
|
khr_storage_buffer_storage_class: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_compute())
|
.iter()
|
||||||
.map(|q| (p, q))
|
.position(|q| q.queue_flags.compute)
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -66,7 +68,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -139,7 +144,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -17,8 +17,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, AttachmentImage, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
@ -73,12 +72,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -100,7 +105,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -109,11 +117,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -313,7 +323,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -26,8 +26,8 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -179,13 +179,19 @@ fn main() {
|
|||||||
fill_mode_non_solid: true,
|
fill_mode_non_solid: true,
|
||||||
..Features::empty()
|
..Features::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
.filter(|&p| p.supported_features().contains(&features))
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
|
.filter(|p| p.supported_features().contains(&features))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -208,7 +214,10 @@ fn main() {
|
|||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
enabled_features: features,
|
enabled_features: features,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -216,11 +225,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -404,7 +415,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -16,8 +16,7 @@ use vulkano::{
|
|||||||
},
|
},
|
||||||
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
descriptor_set::{PersistentDescriptorSet, WriteDescriptorSet},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{
|
image::{
|
||||||
@ -78,12 +77,18 @@ fn main() {
|
|||||||
khr_swapchain: true,
|
khr_swapchain: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
};
|
};
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| p.supported_extensions().contains(&device_extensions))
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| p.supported_extensions().contains(&device_extensions))
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false))
|
.iter()
|
||||||
.map(|q| (p, q))
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
|
})
|
||||||
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| match p.properties().device_type {
|
.min_by_key(|(p, _)| match p.properties().device_type {
|
||||||
PhysicalDeviceType::DiscreteGpu => 0,
|
PhysicalDeviceType::DiscreteGpu => 0,
|
||||||
@ -105,7 +110,10 @@ fn main() {
|
|||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -113,11 +121,13 @@ fn main() {
|
|||||||
let queue = queues.next().unwrap();
|
let queue = queues.next().unwrap();
|
||||||
|
|
||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -314,7 +324,7 @@ fn main() {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -29,8 +29,8 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderingAttachmentInfo, RenderingInfo,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, Features,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, Features, QueueCreateInfo,
|
QueueCreateInfo,
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -106,12 +106,14 @@ fn main() {
|
|||||||
|
|
||||||
// We then choose which physical device to use. First, we enumerate all the available physical
|
// We then choose which physical device to use. First, we enumerate all the available physical
|
||||||
// devices, then apply filters to narrow them down to those that can support our needs.
|
// devices, then apply filters to narrow them down to those that can support our needs.
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| {
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| {
|
||||||
// For this example, we require at least Vulkan 1.3.
|
// For this example, we require at least Vulkan 1.3.
|
||||||
p.api_version() >= Version::V1_3
|
p.api_version() >= Version::V1_3
|
||||||
})
|
})
|
||||||
.filter(|&p| {
|
.filter(|p| {
|
||||||
// Some devices may not support the extensions or features that your application, or
|
// Some devices may not support the extensions or features that your application, or
|
||||||
// report properties and limits that are not sufficient for your application. These
|
// report properties and limits that are not sufficient for your application. These
|
||||||
// should be filtered out here.
|
// should be filtered out here.
|
||||||
@ -130,17 +132,19 @@ fn main() {
|
|||||||
// real-life application, you may want to use a separate dedicated transfer queue to
|
// real-life application, you may want to use a separate dedicated transfer queue to
|
||||||
// handle data transfers in parallel with graphics operations. You may also need a
|
// handle data transfers in parallel with graphics operations. You may also need a
|
||||||
// separate queue for compute operations, if your application uses those.
|
// separate queue for compute operations, if your application uses those.
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| {
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
// We select a queue family that supports graphics operations. When drawing to
|
// We select a queue family that supports graphics operations. When drawing to
|
||||||
// a window surface, as we do in this example, we also need to check that queues
|
// a window surface, as we do in this example, we also need to check that queues
|
||||||
// in this queue family are capable of presenting images to the surface.
|
// in this queue family are capable of presenting images to the surface.
|
||||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
})
|
})
|
||||||
// The code here searches for the first queue family that is suitable. If none is
|
// The code here searches for the first queue family that is suitable. If none is
|
||||||
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
||||||
// device.
|
// device.
|
||||||
.map(|q| (p, q))
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
// All the physical devices that pass the filters above are suitable for the application.
|
// All the physical devices that pass the filters above are suitable for the application.
|
||||||
// However, not every device is equal, some are preferred over others. Now, we assign
|
// However, not every device is equal, some are preferred over others. Now, we assign
|
||||||
@ -194,7 +198,10 @@ fn main() {
|
|||||||
|
|
||||||
// The list of queues that we are going to use. Here we only use one queue, from the
|
// The list of queues that we are going to use. Here we only use one queue, from the
|
||||||
// previously chosen queue family.
|
// previously chosen queue family.
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -212,13 +219,15 @@ fn main() {
|
|||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||||
// pass values that are allowed by the capabilities.
|
// pass values that are allowed by the capabilities.
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Choosing the internal format that the images will have.
|
// Choosing the internal format that the images will have.
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -497,7 +506,7 @@ fn main() {
|
|||||||
// buffer will only be executable on that given queue family.
|
// buffer will only be executable on that given queue family.
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -24,8 +24,7 @@ use vulkano::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
AutoCommandBufferBuilder, CommandBufferUsage, RenderPassBeginInfo, SubpassContents,
|
||||||
},
|
},
|
||||||
device::{
|
device::{
|
||||||
physical::{PhysicalDevice, PhysicalDeviceType},
|
physical::PhysicalDeviceType, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
||||||
Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
},
|
||||||
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
image::{view::ImageView, ImageAccess, ImageUsage, SwapchainImage},
|
||||||
impl_vertex,
|
impl_vertex,
|
||||||
@ -100,8 +99,10 @@ fn main() {
|
|||||||
|
|
||||||
// We then choose which physical device to use. First, we enumerate all the available physical
|
// We then choose which physical device to use. First, we enumerate all the available physical
|
||||||
// devices, then apply filters to narrow them down to those that can support our needs.
|
// devices, then apply filters to narrow them down to those that can support our needs.
|
||||||
let (physical_device, queue_family) = PhysicalDevice::enumerate(&instance)
|
let (physical_device, queue_family_index) = instance
|
||||||
.filter(|&p| {
|
.enumerate_physical_devices()
|
||||||
|
.unwrap()
|
||||||
|
.filter(|p| {
|
||||||
// Some devices may not support the extensions or features that your application, or
|
// Some devices may not support the extensions or features that your application, or
|
||||||
// report properties and limits that are not sufficient for your application. These
|
// report properties and limits that are not sufficient for your application. These
|
||||||
// should be filtered out here.
|
// should be filtered out here.
|
||||||
@ -120,17 +121,19 @@ fn main() {
|
|||||||
// real-life application, you may want to use a separate dedicated transfer queue to
|
// real-life application, you may want to use a separate dedicated transfer queue to
|
||||||
// handle data transfers in parallel with graphics operations. You may also need a
|
// handle data transfers in parallel with graphics operations. You may also need a
|
||||||
// separate queue for compute operations, if your application uses those.
|
// separate queue for compute operations, if your application uses those.
|
||||||
p.queue_families()
|
p.queue_family_properties()
|
||||||
.find(|&q| {
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.position(|(i, q)| {
|
||||||
// We select a queue family that supports graphics operations. When drawing to
|
// We select a queue family that supports graphics operations. When drawing to
|
||||||
// a window surface, as we do in this example, we also need to check that queues
|
// a window surface, as we do in this example, we also need to check that queues
|
||||||
// in this queue family are capable of presenting images to the surface.
|
// in this queue family are capable of presenting images to the surface.
|
||||||
q.supports_graphics() && q.supports_surface(&surface).unwrap_or(false)
|
q.queue_flags.graphics && p.surface_support(i as u32, &surface).unwrap_or(false)
|
||||||
})
|
})
|
||||||
// The code here searches for the first queue family that is suitable. If none is
|
// The code here searches for the first queue family that is suitable. If none is
|
||||||
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
// found, `None` is returned to `filter_map`, which disqualifies this physical
|
||||||
// device.
|
// device.
|
||||||
.map(|q| (p, q))
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
// All the physical devices that pass the filters above are suitable for the application.
|
// All the physical devices that pass the filters above are suitable for the application.
|
||||||
// However, not every device is equal, some are preferred over others. Now, we assign
|
// However, not every device is equal, some are preferred over others. Now, we assign
|
||||||
@ -175,7 +178,10 @@ fn main() {
|
|||||||
|
|
||||||
// The list of queues that we are going to use. Here we only use one queue, from the
|
// The list of queues that we are going to use. Here we only use one queue, from the
|
||||||
// previously chosen queue family.
|
// previously chosen queue family.
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -193,13 +199,15 @@ fn main() {
|
|||||||
let (mut swapchain, images) = {
|
let (mut swapchain, images) = {
|
||||||
// Querying the capabilities of the surface. When we create the swapchain we can only
|
// Querying the capabilities of the surface. When we create the swapchain we can only
|
||||||
// pass values that are allowed by the capabilities.
|
// pass values that are allowed by the capabilities.
|
||||||
let surface_capabilities = physical_device
|
let surface_capabilities = device
|
||||||
|
.physical_device()
|
||||||
.surface_capabilities(&surface, Default::default())
|
.surface_capabilities(&surface, Default::default())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Choosing the internal format that the images will have.
|
// Choosing the internal format that the images will have.
|
||||||
let image_format = Some(
|
let image_format = Some(
|
||||||
physical_device
|
device
|
||||||
|
.physical_device()
|
||||||
.surface_formats(&surface, Default::default())
|
.surface_formats(&surface, Default::default())
|
||||||
.unwrap()[0]
|
.unwrap()[0]
|
||||||
.0,
|
.0,
|
||||||
@ -515,7 +523,7 @@ fn main() {
|
|||||||
// buffer will only be executable on that given queue family.
|
// buffer will only be executable on that given queue family.
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -149,7 +149,9 @@ impl VulkanoContext {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get prioritized device
|
// Get prioritized device
|
||||||
let physical_device = PhysicalDevice::enumerate(&instance)
|
let physical_device = instance
|
||||||
|
.enumerate_physical_devices()
|
||||||
|
.expect("Failed to enumerate physical devices")
|
||||||
.filter(|p| (config.device_filter_fn)(p))
|
.filter(|p| (config.device_filter_fn)(p))
|
||||||
.min_by_key(|p| (config.device_priority_fn)(p))
|
.min_by_key(|p| (config.device_priority_fn)(p))
|
||||||
.expect("Failed to create physical device");
|
.expect("Failed to create physical device");
|
||||||
@ -181,34 +183,49 @@ impl VulkanoContext {
|
|||||||
/// Creates vulkano device with required queue families and required extensions. Creates a
|
/// Creates vulkano device with required queue families and required extensions. Creates a
|
||||||
/// separate queue for compute if possible. If not, same queue as graphics is used.
|
/// separate queue for compute if possible. If not, same queue as graphics is used.
|
||||||
fn create_device(
|
fn create_device(
|
||||||
physical: PhysicalDevice,
|
physical_device: Arc<PhysicalDevice>,
|
||||||
device_extensions: DeviceExtensions,
|
device_extensions: DeviceExtensions,
|
||||||
features: Features,
|
features: Features,
|
||||||
) -> (Arc<Device>, Arc<Queue>, Arc<Queue>) {
|
) -> (Arc<Device>, Arc<Queue>, Arc<Queue>) {
|
||||||
let (gfx_index, queue_family_graphics) = physical
|
let queue_family_graphics = physical_device
|
||||||
.queue_families()
|
.queue_family_properties()
|
||||||
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(_i, q)| q.supports_graphics())
|
.map(|(i, q)| (i as u32, q))
|
||||||
|
.find(|(_i, q)| q.queue_flags.graphics)
|
||||||
|
.map(|(i, _)| i)
|
||||||
.expect("Could not find a queue that supports graphics");
|
.expect("Could not find a queue that supports graphics");
|
||||||
// Try finding a separate queue for compute
|
// Try finding a separate queue for compute
|
||||||
let compute_family_data = physical
|
let queue_family_compute = physical_device
|
||||||
.queue_families()
|
.queue_family_properties()
|
||||||
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|&(i, q)| q.supports_compute() && i != gfx_index);
|
.map(|(i, q)| (i as u32, q))
|
||||||
|
.find(|(i, q)| q.queue_flags.compute && *i != queue_family_graphics)
|
||||||
|
.map(|(i, _)| i);
|
||||||
|
let is_separate_compute_queue = queue_family_compute.is_some();
|
||||||
|
|
||||||
let is_separate_compute_queue = compute_family_data.is_some();
|
let queue_create_infos = if let Some(queue_family_compute) = queue_family_compute {
|
||||||
let queue_create_infos = if is_separate_compute_queue {
|
|
||||||
let (_i, queue_family_compute) = compute_family_data.unwrap();
|
|
||||||
vec![
|
vec![
|
||||||
QueueCreateInfo::family(queue_family_graphics),
|
QueueCreateInfo {
|
||||||
QueueCreateInfo::family(queue_family_compute),
|
queue_family_index: queue_family_graphics,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
QueueCreateInfo {
|
||||||
|
queue_family_index: queue_family_compute,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
vec![QueueCreateInfo::family(queue_family_graphics)]
|
vec![QueueCreateInfo {
|
||||||
|
queue_family_index: queue_family_graphics,
|
||||||
|
..Default::default()
|
||||||
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
let (device, mut queues) = {
|
let (device, mut queues) = {
|
||||||
Device::new(
|
Device::new(
|
||||||
physical,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_extensions: device_extensions,
|
enabled_extensions: device_extensions,
|
||||||
enabled_features: features,
|
enabled_features: features,
|
||||||
|
@ -40,3 +40,6 @@ regex = "1.5"
|
|||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
vk-parse = "0.7"
|
vk-parse = "0.7"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
document_unchecked = []
|
||||||
|
@ -339,9 +339,9 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let from_cstr_for_extensions_items =
|
let from_str_for_extensions_items =
|
||||||
members.iter().map(|ExtensionsMember { name, raw, .. }| {
|
members.iter().map(|ExtensionsMember { name, raw, .. }| {
|
||||||
let raw = Literal::byte_string(raw.as_bytes());
|
let raw = Literal::string(raw);
|
||||||
quote! {
|
quote! {
|
||||||
#raw => { extensions.#name = true; }
|
#raw => { extensions.#name = true; }
|
||||||
}
|
}
|
||||||
@ -519,12 +519,14 @@ fn extensions_common_output(struct_name: Ident, members: &[ExtensionsMember]) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, I> From<I> for #struct_name where I: IntoIterator<Item = &'a std::ffi::CStr> {
|
impl<'a> FromIterator<&'a str> for #struct_name {
|
||||||
fn from(names: I) -> Self {
|
fn from_iter<I>(iter: I) -> Self
|
||||||
|
where I: IntoIterator<Item = &'a str>
|
||||||
|
{
|
||||||
let mut extensions = Self::empty();
|
let mut extensions = Self::empty();
|
||||||
for name in names {
|
for name in iter {
|
||||||
match name.to_bytes() {
|
match name {
|
||||||
#(#from_cstr_for_extensions_items)*
|
#(#from_str_for_extensions_items)*
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
buffer::{sys::UnsafeBufferCreateInfo, BufferCreationError, TypedBufferAccess},
|
buffer::{sys::UnsafeBufferCreateInfo, BufferCreationError, TypedBufferAccess},
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
memory::{
|
memory::{
|
||||||
pool::{
|
pool::{
|
||||||
AllocFromRequirementsFilter, AllocLayout, MappingRequirement, MemoryPoolAlloc,
|
AllocFromRequirementsFilter, AllocLayout, MappingRequirement, MemoryPoolAlloc,
|
||||||
@ -62,7 +62,7 @@ where
|
|||||||
memory: A,
|
memory: A,
|
||||||
|
|
||||||
// Queue families allowed to access this buffer.
|
// Queue families allowed to access this buffer.
|
||||||
queue_families: SmallVec<[u32; 4]>,
|
queue_family_indices: SmallVec<[u32; 4]>,
|
||||||
|
|
||||||
// Necessary to make it compile.
|
// Necessary to make it compile.
|
||||||
marker: PhantomData<Box<T>>,
|
marker: PhantomData<Box<T>>,
|
||||||
@ -203,27 +203,21 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `size` is zero.
|
/// - Panics if `size` is zero.
|
||||||
pub unsafe fn raw<'a, I>(
|
pub unsafe fn raw(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
host_cached: bool,
|
host_cached: bool,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<CpuAccessibleBuffer<T>>, DeviceMemoryAllocationError>
|
) -> Result<Arc<CpuAccessibleBuffer<T>>, DeviceMemoryAllocationError> {
|
||||||
where
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
let queue_families = queue_families
|
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let buffer = {
|
let buffer = {
|
||||||
match UnsafeBuffer::new(
|
match UnsafeBuffer::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
UnsafeBufferCreateInfo {
|
UnsafeBufferCreateInfo {
|
||||||
sharing: if queue_families.len() >= 2 {
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
Sharing::Concurrent(queue_families.clone())
|
Sharing::Concurrent(queue_family_indices.clone())
|
||||||
} else {
|
} else {
|
||||||
Sharing::Exclusive
|
Sharing::Exclusive
|
||||||
},
|
},
|
||||||
@ -247,7 +241,7 @@ where
|
|||||||
MappingRequirement::Map,
|
MappingRequirement::Map,
|
||||||
Some(DedicatedAllocation::Buffer(&buffer)),
|
Some(DedicatedAllocation::Buffer(&buffer)),
|
||||||
|m| {
|
|m| {
|
||||||
if m.is_host_cached() {
|
if m.property_flags.host_cached {
|
||||||
if host_cached {
|
if host_cached {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
@ -269,7 +263,7 @@ where
|
|||||||
Ok(Arc::new(CpuAccessibleBuffer {
|
Ok(Arc::new(CpuAccessibleBuffer {
|
||||||
inner: buffer,
|
inner: buffer,
|
||||||
memory,
|
memory,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -280,18 +274,9 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
/// Returns the queue families this buffer can be used on.
|
/// Returns the queue families this buffer can be used on.
|
||||||
// TODO: use a custom iterator
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn queue_families(&self) -> Vec<QueueFamily> {
|
pub fn queue_family_indices(&self) -> &[u32] {
|
||||||
self.queue_families
|
&self.queue_family_indices
|
||||||
.iter()
|
|
||||||
.map(|&num| {
|
|
||||||
self.device()
|
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(num)
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ use std::{
|
|||||||
/// let sub_buffer = buffer.next(data).unwrap();
|
/// let sub_buffer = buffer.next(data).unwrap();
|
||||||
///
|
///
|
||||||
/// // You can then use `sub_buffer` as if it was an entirely separate buffer.
|
/// // You can then use `sub_buffer` as if it was an entirely separate buffer.
|
||||||
/// AutoCommandBufferBuilder::primary(device.clone(), queue.family(), CommandBufferUsage::OneTimeSubmit)
|
/// AutoCommandBufferBuilder::primary(device.clone(), queue.queue_family_index(), CommandBufferUsage::OneTimeSubmit)
|
||||||
/// .unwrap()
|
/// .unwrap()
|
||||||
/// // For the sake of the example we just call `update_buffer` on the buffer, even though
|
/// // For the sake of the example we just call `update_buffer` on the buffer, even though
|
||||||
/// // it is pointless to do that.
|
/// // it is pointless to do that.
|
||||||
|
@ -24,7 +24,7 @@ use crate::{
|
|||||||
AutoCommandBufferBuilder, CommandBufferBeginError, CommandBufferExecFuture,
|
AutoCommandBufferBuilder, CommandBufferBeginError, CommandBufferExecFuture,
|
||||||
CommandBufferUsage, CopyBufferInfo, PrimaryAutoCommandBuffer, PrimaryCommandBuffer,
|
CommandBufferUsage, CopyBufferInfo, PrimaryAutoCommandBuffer, PrimaryCommandBuffer,
|
||||||
},
|
},
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
device::{Device, DeviceOwned, Queue},
|
||||||
memory::{
|
memory::{
|
||||||
pool::{
|
pool::{
|
||||||
alloc_dedicated_with_exportable_fd, AllocFromRequirementsFilter, AllocLayout,
|
alloc_dedicated_with_exportable_fd, AllocFromRequirementsFilter, AllocLayout,
|
||||||
@ -99,14 +99,14 @@ use std::{
|
|||||||
/// transfer_dst: true,
|
/// transfer_dst: true,
|
||||||
/// ..BufferUsage::empty()
|
/// ..BufferUsage::empty()
|
||||||
/// }, // Specify use as a storage buffer and transfer destination.
|
/// }, // Specify use as a storage buffer and transfer destination.
|
||||||
/// device.active_queue_families(),
|
/// device.active_queue_family_indices().iter().copied(),
|
||||||
/// )
|
/// )
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
///
|
///
|
||||||
/// // Create a one-time command to copy between the buffers.
|
/// // Create a one-time command to copy between the buffers.
|
||||||
/// let mut cbb = AutoCommandBufferBuilder::primary(
|
/// let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
/// device.clone(),
|
/// device.clone(),
|
||||||
/// queue.family(),
|
/// queue.queue_family_index(),
|
||||||
/// CommandBufferUsage::OneTimeSubmit,
|
/// CommandBufferUsage::OneTimeSubmit,
|
||||||
/// )
|
/// )
|
||||||
/// .unwrap();
|
/// .unwrap();
|
||||||
@ -138,7 +138,7 @@ where
|
|||||||
memory: A,
|
memory: A,
|
||||||
|
|
||||||
// Queue families allowed to access this buffer.
|
// Queue families allowed to access this buffer.
|
||||||
queue_families: SmallVec<[u32; 4]>,
|
queue_family_indices: SmallVec<[u32; 4]>,
|
||||||
|
|
||||||
// Necessary to make it compile.
|
// Necessary to make it compile.
|
||||||
marker: PhantomData<Box<T>>,
|
marker: PhantomData<Box<T>>,
|
||||||
@ -154,16 +154,18 @@ where
|
|||||||
///
|
///
|
||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<'a, I>(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
unsafe {
|
unsafe {
|
||||||
DeviceLocalBuffer::raw(device, size_of::<T>() as DeviceSize, usage, queue_families)
|
DeviceLocalBuffer::raw(
|
||||||
|
device,
|
||||||
|
size_of::<T>() as DeviceSize,
|
||||||
|
usage,
|
||||||
|
queue_family_indices,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -204,12 +206,16 @@ where
|
|||||||
source.device().clone(),
|
source.device().clone(),
|
||||||
source.size(),
|
source.size(),
|
||||||
actual_usage,
|
actual_usage,
|
||||||
source.device().active_queue_families(),
|
source
|
||||||
|
.device()
|
||||||
|
.active_queue_family_indices()
|
||||||
|
.iter()
|
||||||
|
.copied(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
source.device().clone(),
|
source.device().clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
)?;
|
)?;
|
||||||
cbb.copy_buffer(CopyBufferInfo::buffers(source, buffer.clone()))
|
cbb.copy_buffer(CopyBufferInfo::buffers(source, buffer.clone()))
|
||||||
@ -312,21 +318,18 @@ where
|
|||||||
/// - Panics if `T` has zero size.
|
/// - Panics if `T` has zero size.
|
||||||
/// - Panics if `len` is zero.
|
/// - Panics if `len` is zero.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn array<'a, I>(
|
pub fn array(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
len: DeviceSize,
|
len: DeviceSize,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<DeviceLocalBuffer<[T]>>, DeviceMemoryAllocationError>
|
) -> Result<Arc<DeviceLocalBuffer<[T]>>, DeviceMemoryAllocationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
unsafe {
|
unsafe {
|
||||||
DeviceLocalBuffer::raw(
|
DeviceLocalBuffer::raw(
|
||||||
device,
|
device,
|
||||||
len * size_of::<T>() as DeviceSize,
|
len * size_of::<T>() as DeviceSize,
|
||||||
usage,
|
usage,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -345,21 +348,15 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `size` is zero.
|
/// - Panics if `size` is zero.
|
||||||
pub unsafe fn raw<'a, I>(
|
pub unsafe fn raw(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||||
where
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
let queue_families = queue_families
|
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_families)?;
|
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_family_indices)?;
|
||||||
|
|
||||||
let memory = MemoryPool::alloc_from_requirements(
|
let memory = MemoryPool::alloc_from_requirements(
|
||||||
device.standard_memory_pool(),
|
device.standard_memory_pool(),
|
||||||
@ -368,7 +365,7 @@ where
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
Some(DedicatedAllocation::Buffer(&buffer)),
|
Some(DedicatedAllocation::Buffer(&buffer)),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -381,7 +378,7 @@ where
|
|||||||
Ok(Arc::new(DeviceLocalBuffer {
|
Ok(Arc::new(DeviceLocalBuffer {
|
||||||
inner: buffer,
|
inner: buffer,
|
||||||
memory,
|
memory,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -391,24 +388,18 @@ where
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
///
|
///
|
||||||
/// - Panics if `size` is zero.
|
/// - Panics if `size` is zero.
|
||||||
pub unsafe fn raw_with_exportable_fd<'a, I>(
|
pub unsafe fn raw_with_exportable_fd(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError>
|
) -> Result<Arc<DeviceLocalBuffer<T>>, DeviceMemoryAllocationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
assert!(device.enabled_extensions().khr_external_memory_fd);
|
assert!(device.enabled_extensions().khr_external_memory_fd);
|
||||||
assert!(device.enabled_extensions().khr_external_memory);
|
assert!(device.enabled_extensions().khr_external_memory);
|
||||||
|
|
||||||
let queue_families = queue_families
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_families)?;
|
let (buffer, mem_reqs) = Self::build_buffer(&device, size, usage, &queue_family_indices)?;
|
||||||
|
|
||||||
let memory = alloc_dedicated_with_exportable_fd(
|
let memory = alloc_dedicated_with_exportable_fd(
|
||||||
device,
|
device,
|
||||||
@ -417,7 +408,7 @@ where
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
DedicatedAllocation::Buffer(&buffer),
|
DedicatedAllocation::Buffer(&buffer),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -431,7 +422,7 @@ where
|
|||||||
Ok(Arc::new(DeviceLocalBuffer {
|
Ok(Arc::new(DeviceLocalBuffer {
|
||||||
inner: buffer,
|
inner: buffer,
|
||||||
memory,
|
memory,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
marker: PhantomData,
|
marker: PhantomData,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@ -440,14 +431,14 @@ where
|
|||||||
device: &Arc<Device>,
|
device: &Arc<Device>,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
usage: BufferUsage,
|
usage: BufferUsage,
|
||||||
queue_families: &SmallVec<[u32; 4]>,
|
queue_family_indices: &SmallVec<[u32; 4]>,
|
||||||
) -> Result<(Arc<UnsafeBuffer>, MemoryRequirements), DeviceMemoryAllocationError> {
|
) -> Result<(Arc<UnsafeBuffer>, MemoryRequirements), DeviceMemoryAllocationError> {
|
||||||
let buffer = {
|
let buffer = {
|
||||||
match UnsafeBuffer::new(
|
match UnsafeBuffer::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
UnsafeBufferCreateInfo {
|
UnsafeBufferCreateInfo {
|
||||||
sharing: if queue_families.len() >= 2 {
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
Sharing::Concurrent(queue_families.clone())
|
Sharing::Concurrent(queue_family_indices.clone())
|
||||||
} else {
|
} else {
|
||||||
Sharing::Exclusive
|
Sharing::Exclusive
|
||||||
},
|
},
|
||||||
@ -481,18 +472,9 @@ where
|
|||||||
T: BufferContents + ?Sized,
|
T: BufferContents + ?Sized,
|
||||||
{
|
{
|
||||||
/// Returns the queue families this buffer can be used on.
|
/// Returns the queue families this buffer can be used on.
|
||||||
// TODO: use a custom iterator
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn queue_families(&self) -> Vec<QueueFamily> {
|
pub fn queue_family_indices(&self) -> &[u32] {
|
||||||
self.queue_families
|
&self.queue_family_indices
|
||||||
.iter()
|
|
||||||
.map(|&num| {
|
|
||||||
self.device()
|
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(num)
|
|
||||||
.unwrap()
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,7 +628,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -691,7 +673,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -135,20 +135,31 @@ impl UnsafeBuffer {
|
|||||||
// Check sharing mode and queue families
|
// Check sharing mode and queue families
|
||||||
let (sharing_mode, queue_family_indices) = match &mut sharing {
|
let (sharing_mode, queue_family_indices) = match &mut sharing {
|
||||||
Sharing::Exclusive => (ash::vk::SharingMode::EXCLUSIVE, &[] as _),
|
Sharing::Exclusive => (ash::vk::SharingMode::EXCLUSIVE, &[] as _),
|
||||||
Sharing::Concurrent(ids) => {
|
Sharing::Concurrent(queue_family_indices) => {
|
||||||
// VUID-VkBufferCreateInfo-sharingMode-00914
|
// VUID-VkBufferCreateInfo-sharingMode-00914
|
||||||
ids.sort_unstable();
|
queue_family_indices.sort_unstable();
|
||||||
ids.dedup();
|
queue_family_indices.dedup();
|
||||||
assert!(ids.len() >= 2);
|
assert!(queue_family_indices.len() >= 2);
|
||||||
|
|
||||||
for &id in ids.iter() {
|
for &queue_family_index in queue_family_indices.iter() {
|
||||||
// VUID-VkBufferCreateInfo-sharingMode-01419
|
// VUID-VkBufferCreateInfo-sharingMode-01419
|
||||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
if queue_family_index
|
||||||
return Err(BufferCreationError::SharingInvalidQueueFamilyId { id });
|
>= device.physical_device().queue_family_properties().len() as u32
|
||||||
|
{
|
||||||
|
return Err(BufferCreationError::SharingQueueFamilyIndexOutOfRange {
|
||||||
|
queue_family_index,
|
||||||
|
queue_family_count: device
|
||||||
|
.physical_device()
|
||||||
|
.queue_family_properties()
|
||||||
|
.len() as u32,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(ash::vk::SharingMode::CONCURRENT, ids.as_slice())
|
(
|
||||||
|
ash::vk::SharingMode::CONCURRENT,
|
||||||
|
queue_family_indices.as_slice(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -332,7 +343,7 @@ impl UnsafeBuffer {
|
|||||||
let mem_reqs = mem_reqs.assume_init();
|
let mem_reqs = mem_reqs.assume_init();
|
||||||
mem_reqs.size <= (memory.allocation_size() - offset)
|
mem_reqs.size <= (memory.allocation_size() - offset)
|
||||||
&& (offset % mem_reqs.alignment) == 0
|
&& (offset % mem_reqs.alignment) == 0
|
||||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type().id()) != 0
|
&& mem_reqs.memory_type_bits & (1 << memory.memory_type_index()) != 0
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for alignment correctness.
|
// Check for alignment correctness.
|
||||||
@ -479,9 +490,12 @@ pub enum BufferCreationError {
|
|||||||
/// The specified size exceeded the value of the `max_buffer_size` limit.
|
/// The specified size exceeded the value of the `max_buffer_size` limit.
|
||||||
MaxBufferSizeExceeded { size: DeviceSize, max: DeviceSize },
|
MaxBufferSizeExceeded { size: DeviceSize, max: DeviceSize },
|
||||||
|
|
||||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family ids was not
|
/// The sharing mode was set to `Concurrent`, but one of the specified queue family indices was
|
||||||
/// valid.
|
/// out of range.
|
||||||
SharingInvalidQueueFamilyId { id: u32 },
|
SharingQueueFamilyIndexOutOfRange {
|
||||||
|
queue_family_index: u32,
|
||||||
|
queue_family_count: u32,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error for BufferCreationError {
|
impl Error for BufferCreationError {
|
||||||
@ -511,8 +525,8 @@ impl Display for BufferCreationError {
|
|||||||
f,
|
f,
|
||||||
"the specified size exceeded the value of the `max_buffer_size` limit"
|
"the specified size exceeded the value of the `max_buffer_size` limit"
|
||||||
),
|
),
|
||||||
Self::SharingInvalidQueueFamilyId { .. } => {
|
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
|
||||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family ids was not valid")
|
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ use super::{
|
|||||||
use crate::{
|
use crate::{
|
||||||
buffer::{sys::UnsafeBuffer, BufferAccess},
|
buffer::{sys::UnsafeBuffer, BufferAccess},
|
||||||
command_buffer::CommandBufferInheritanceRenderingInfo,
|
command_buffer::CommandBufferInheritanceRenderingInfo,
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
device::{physical::QueueFamilyProperties, Device, DeviceOwned, Queue},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{sys::UnsafeImage, ImageAccess, ImageLayout, ImageSubresourceRange},
|
image::{sys::UnsafeImage, ImageAccess, ImageLayout, ImageSubresourceRange},
|
||||||
query::{QueryControlFlags, QueryType},
|
query::{QueryControlFlags, QueryType},
|
||||||
@ -49,8 +49,8 @@ pub struct AutoCommandBufferBuilder<L, P = StandardCommandPoolBuilder> {
|
|||||||
pub(super) inner: SyncCommandBufferBuilder,
|
pub(super) inner: SyncCommandBufferBuilder,
|
||||||
pool_builder_alloc: P, // Safety: must be dropped after `inner`
|
pool_builder_alloc: P, // Safety: must be dropped after `inner`
|
||||||
|
|
||||||
// The queue family that this command buffer is being created for.
|
// The index of the queue family that this command buffer is being created for.
|
||||||
queue_family_id: u32,
|
queue_family_index: u32,
|
||||||
|
|
||||||
// The inheritance for secondary command buffers.
|
// The inheritance for secondary command buffers.
|
||||||
// Must be `None` in a primary command buffer and `Some` in a secondary command buffer.
|
// Must be `None` in a primary command buffer and `Some` in a secondary command buffer.
|
||||||
@ -129,7 +129,7 @@ impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuild
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn primary(
|
pub fn primary(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue_family: QueueFamily,
|
queue_family_index: u32,
|
||||||
usage: CommandBufferUsage,
|
usage: CommandBufferUsage,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
|
AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuilder>,
|
||||||
@ -138,7 +138,7 @@ impl AutoCommandBufferBuilder<PrimaryAutoCommandBuffer, StandardCommandPoolBuild
|
|||||||
unsafe {
|
unsafe {
|
||||||
AutoCommandBufferBuilder::begin(
|
AutoCommandBufferBuilder::begin(
|
||||||
device,
|
device,
|
||||||
queue_family,
|
queue_family_index,
|
||||||
CommandBufferLevel::Primary,
|
CommandBufferLevel::Primary,
|
||||||
CommandBufferBeginInfo {
|
CommandBufferBeginInfo {
|
||||||
usage,
|
usage,
|
||||||
@ -155,7 +155,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn secondary(
|
pub fn secondary(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue_family: QueueFamily,
|
queue_family_index: u32,
|
||||||
usage: CommandBufferUsage,
|
usage: CommandBufferUsage,
|
||||||
inheritance_info: CommandBufferInheritanceInfo,
|
inheritance_info: CommandBufferInheritanceInfo,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
@ -165,7 +165,7 @@ impl AutoCommandBufferBuilder<SecondaryAutoCommandBuffer, StandardCommandPoolBui
|
|||||||
unsafe {
|
unsafe {
|
||||||
AutoCommandBufferBuilder::begin(
|
AutoCommandBufferBuilder::begin(
|
||||||
device,
|
device,
|
||||||
queue_family,
|
queue_family_index,
|
||||||
CommandBufferLevel::Secondary,
|
CommandBufferLevel::Secondary,
|
||||||
CommandBufferBeginInfo {
|
CommandBufferBeginInfo {
|
||||||
usage,
|
usage,
|
||||||
@ -183,12 +183,12 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
|||||||
// `begin_info.inheritance_info` must match `level`.
|
// `begin_info.inheritance_info` must match `level`.
|
||||||
unsafe fn begin(
|
unsafe fn begin(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue_family: QueueFamily,
|
queue_family_index: u32,
|
||||||
level: CommandBufferLevel,
|
level: CommandBufferLevel,
|
||||||
begin_info: CommandBufferBeginInfo,
|
begin_info: CommandBufferBeginInfo,
|
||||||
) -> Result<AutoCommandBufferBuilder<L, StandardCommandPoolBuilder>, CommandBufferBeginError>
|
) -> Result<AutoCommandBufferBuilder<L, StandardCommandPoolBuilder>, CommandBufferBeginError>
|
||||||
{
|
{
|
||||||
Self::validate_begin(&device, &queue_family, level, &begin_info)?;
|
Self::validate_begin(&device, queue_family_index, level, &begin_info)?;
|
||||||
|
|
||||||
let &CommandBufferBeginInfo {
|
let &CommandBufferBeginInfo {
|
||||||
usage,
|
usage,
|
||||||
@ -252,7 +252,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
device.with_standard_command_pool(queue_family, |pool| {
|
device.with_standard_command_pool(queue_family_index, |pool| {
|
||||||
let pool_builder_alloc = pool
|
let pool_builder_alloc = pool
|
||||||
.allocate(level, 1)?
|
.allocate(level, 1)?
|
||||||
.next()
|
.next()
|
||||||
@ -263,7 +263,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
|||||||
Ok(AutoCommandBufferBuilder {
|
Ok(AutoCommandBufferBuilder {
|
||||||
inner,
|
inner,
|
||||||
pool_builder_alloc,
|
pool_builder_alloc,
|
||||||
queue_family_id: queue_family.id(),
|
queue_family_index,
|
||||||
render_pass_state,
|
render_pass_state,
|
||||||
query_state: HashMap::default(),
|
query_state: HashMap::default(),
|
||||||
inheritance_info,
|
inheritance_info,
|
||||||
@ -275,7 +275,7 @@ impl<L> AutoCommandBufferBuilder<L, StandardCommandPoolBuilder> {
|
|||||||
|
|
||||||
fn validate_begin(
|
fn validate_begin(
|
||||||
device: &Device,
|
device: &Device,
|
||||||
_queue_family: &QueueFamily,
|
_queue_family_index: u32,
|
||||||
level: CommandBufferLevel,
|
level: CommandBufferLevel,
|
||||||
begin_info: &CommandBufferBeginInfo,
|
begin_info: &CommandBufferBeginInfo,
|
||||||
) -> Result<(), CommandBufferBeginError> {
|
) -> Result<(), CommandBufferBeginError> {
|
||||||
@ -694,11 +694,8 @@ impl From<OomError> for BuildError {
|
|||||||
|
|
||||||
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
impl<L, P> AutoCommandBufferBuilder<L, P> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn queue_family(&self) -> QueueFamily {
|
pub(super) fn queue_family_properties(&self) -> &QueueFamilyProperties {
|
||||||
self.device()
|
&self.device().physical_device().queue_family_properties()[self.queue_family_index as usize]
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(self.queue_family_id)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the binding/setting state.
|
/// Returns the binding/setting state.
|
||||||
@ -965,27 +962,25 @@ mod tests {
|
|||||||
synced::SyncCommandBufferBuilderError, BufferCopy, CopyBufferInfoTyped, CopyError,
|
synced::SyncCommandBufferBuilderError, BufferCopy, CopyBufferInfoTyped, CopyError,
|
||||||
ExecuteCommandsError,
|
ExecuteCommandsError,
|
||||||
},
|
},
|
||||||
device::{physical::PhysicalDevice, DeviceCreateInfo, QueueCreateInfo},
|
device::{DeviceCreateInfo, QueueCreateInfo},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn copy_buffer_dimensions() {
|
fn copy_buffer_dimensions() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
|
|
||||||
let phys = match PhysicalDevice::enumerate(&instance).next() {
|
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let queue_family = match phys.queue_families().next() {
|
|
||||||
Some(q) => q,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
|
|
||||||
let (device, mut queues) = Device::new(
|
let (device, mut queues) = Device::new(
|
||||||
phys,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index: 0,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -1017,7 +1012,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1055,7 +1050,7 @@ mod tests {
|
|||||||
// Make a secondary CB that doesn't support simultaneous use.
|
// Make a secondary CB that doesn't support simultaneous use.
|
||||||
let builder = AutoCommandBufferBuilder::secondary(
|
let builder = AutoCommandBufferBuilder::secondary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
@ -1065,7 +1060,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::SimultaneousUse,
|
CommandBufferUsage::SimultaneousUse,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1088,7 +1083,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::SimultaneousUse,
|
CommandBufferUsage::SimultaneousUse,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1097,7 +1092,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::SimultaneousUse,
|
CommandBufferUsage::SimultaneousUse,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1138,7 +1133,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -1188,7 +1183,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut builder = AutoCommandBufferBuilder::primary(
|
let mut builder = AutoCommandBufferBuilder::primary(
|
||||||
device,
|
device,
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -94,16 +94,18 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-parameter
|
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-parameter
|
||||||
pipeline_bind_point.validate_device(self.device())?;
|
pipeline_bind_point.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBindDescriptorSets-commandBuffer-cmdpool
|
// VUID-vkCmdBindDescriptorSets-commandBuffer-cmdpool
|
||||||
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-00361
|
// VUID-vkCmdBindDescriptorSets-pipelineBindPoint-00361
|
||||||
match pipeline_bind_point {
|
match pipeline_bind_point {
|
||||||
PipelineBindPoint::Compute => {
|
PipelineBindPoint::Compute => {
|
||||||
if !self.queue_family().supports_compute() {
|
if !queue_family_properties.queue_flags.compute {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineBindPoint::Graphics => {
|
PipelineBindPoint::Graphics => {
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,8 +173,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
index_buffer: &dyn BufferAccess,
|
index_buffer: &dyn BufferAccess,
|
||||||
index_type: IndexType,
|
index_type: IndexType,
|
||||||
) -> Result<(), BindPushError> {
|
) -> Result<(), BindPushError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBindIndexBuffer-commandBuffer-cmdpool
|
// VUID-vkCmdBindIndexBuffer-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,8 +225,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
&self,
|
&self,
|
||||||
pipeline: &ComputePipeline,
|
pipeline: &ComputePipeline,
|
||||||
) -> Result<(), BindPushError> {
|
) -> Result<(), BindPushError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBindPipeline-pipelineBindPoint-00777
|
// VUID-vkCmdBindPipeline-pipelineBindPoint-00777
|
||||||
if !self.queue_family().supports_compute() {
|
if !queue_family_properties.queue_flags.compute {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -252,8 +258,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
&self,
|
&self,
|
||||||
pipeline: &GraphicsPipeline,
|
pipeline: &GraphicsPipeline,
|
||||||
) -> Result<(), BindPushError> {
|
) -> Result<(), BindPushError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBindPipeline-pipelineBindPoint-00778
|
// VUID-vkCmdBindPipeline-pipelineBindPoint-00778
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,8 +347,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
first_binding: u32,
|
first_binding: u32,
|
||||||
vertex_buffers: &[Arc<dyn BufferAccess>],
|
vertex_buffers: &[Arc<dyn BufferAccess>],
|
||||||
) -> Result<(), BindPushError> {
|
) -> Result<(), BindPushError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBindVertexBuffers-commandBuffer-cmdpool
|
// VUID-vkCmdBindVertexBuffers-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,16 +560,18 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-parameter
|
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-parameter
|
||||||
pipeline_bind_point.validate_device(self.device())?;
|
pipeline_bind_point.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool
|
// VUID-vkCmdPushDescriptorSetKHR-commandBuffer-cmdpool
|
||||||
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363
|
// VUID-vkCmdPushDescriptorSetKHR-pipelineBindPoint-00363
|
||||||
match pipeline_bind_point {
|
match pipeline_bind_point {
|
||||||
PipelineBindPoint::Compute => {
|
PipelineBindPoint::Compute => {
|
||||||
if !self.queue_family().supports_compute() {
|
if !queue_family_properties.queue_flags.compute {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineBindPoint::Graphics => {
|
PipelineBindPoint::Graphics => {
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(BindPushError::NotSupportedByQueueFamily);
|
return Err(BindPushError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBeginDebugUtilsLabelEXT-commandBuffer-cmdpool
|
// VUID-vkCmdBeginDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,8 +107,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-cmdpool
|
// VUID-vkCmdEndDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,8 +159,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdInsertDebugUtilsLabelEXT-commandBuffer-cmdpool
|
// VUID-vkCmdInsertDebugUtilsLabelEXT-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
return Err(DebugUtilsError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,8 +75,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::BlendConstants)?;
|
self.validate_pipeline_fixed_state(DynamicState::BlendConstants)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetBlendConstants-commandBuffer-cmdpool
|
// VUID-vkCmdSetBlendConstants-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +119,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::ColorWriteEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::ColorWriteEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetColorWriteEnableEXT-commandBuffer-cmdpool
|
// VUID-vkCmdSetColorWriteEnableEXT-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,8 +183,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetCullMode-cullMode-parameter
|
// VUID-vkCmdSetCullMode-cullMode-parameter
|
||||||
cull_mode.validate_device(self.device())?;
|
cull_mode.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetCullMode-commandBuffer-cmdpool
|
// VUID-vkCmdSetCullMode-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,8 +241,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthBias)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthBias)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthBias-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthBias-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,8 +285,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_depth_bias_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
fn validate_set_depth_bias_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthBiasEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthBiasEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthBiasEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthBiasEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,8 +335,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthBounds)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthBounds)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthBounds-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthBounds-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,8 +388,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthBoundsTestEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthBoundsTestEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthBoundsTestEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -427,8 +441,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetDepthCompareOp-depthCompareOp-parameter
|
// VUID-vkCmdSetDepthCompareOp-depthCompareOp-parameter
|
||||||
compare_op.validate_device(self.device())?;
|
compare_op.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthCompareOp-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthCompareOp-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,8 +488,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_depth_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
fn validate_set_depth_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthTestEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthTestEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthTestEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthTestEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,8 +535,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_depth_write_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
fn validate_set_depth_write_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DepthWriteEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::DepthWriteEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDepthWriteEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetDepthWriteEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,8 +594,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::DiscardRectangle)?;
|
self.validate_pipeline_fixed_state(DynamicState::DiscardRectangle)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetDiscardRectangle-commandBuffer-cmdpool
|
// VUID-vkCmdSetDiscardRectangle-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -638,8 +660,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetFrontFace-frontFace-parameter
|
// VUID-vkCmdSetFrontFace-frontFace-parameter
|
||||||
face.validate_device(self.device())?;
|
face.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetFrontFace-commandBuffer-cmdpool
|
// VUID-vkCmdSetFrontFace-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -687,8 +711,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::LineStipple)?;
|
self.validate_pipeline_fixed_state(DynamicState::LineStipple)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetLineStippleEXT-commandBuffer-cmdpool
|
// VUID-vkCmdSetLineStippleEXT-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -731,8 +757,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_line_width(&self, line_width: f32) -> Result<(), SetDynamicStateError> {
|
fn validate_set_line_width(&self, line_width: f32) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::LineWidth)?;
|
self.validate_pipeline_fixed_state(DynamicState::LineWidth)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetLineWidth-commandBuffer-cmdpool
|
// VUID-vkCmdSetLineWidth-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,8 +804,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetLogicOpEXT-logicOp-parameter
|
// VUID-vkCmdSetLogicOpEXT-logicOp-parameter
|
||||||
logic_op.validate_device(self.device())?;
|
logic_op.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetLogicOpEXT-commandBuffer-cmdpool
|
// VUID-vkCmdSetLogicOpEXT-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,8 +856,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_patch_control_points(&self, num: u32) -> Result<(), SetDynamicStateError> {
|
fn validate_set_patch_control_points(&self, num: u32) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::PatchControlPoints)?;
|
self.validate_pipeline_fixed_state(DynamicState::PatchControlPoints)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetPatchControlPointsEXT-commandBuffer-cmdpool
|
// VUID-vkCmdSetPatchControlPointsEXT-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,8 +928,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::PrimitiveRestartEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::PrimitiveRestartEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetPrimitiveRestartEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetPrimitiveRestartEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -951,8 +985,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetPrimitiveTopology-primitiveTopology-parameter
|
// VUID-vkCmdSetPrimitiveTopology-primitiveTopology-parameter
|
||||||
topology.validate_device(self.device())?;
|
topology.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetPrimitiveTopology-commandBuffer-cmdpool
|
// VUID-vkCmdSetPrimitiveTopology-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1031,8 +1067,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::RasterizerDiscardEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::RasterizerDiscardEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetRasterizerDiscardEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1084,8 +1122,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::Scissor)?;
|
self.validate_pipeline_fixed_state(DynamicState::Scissor)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetScissor-commandBuffer-cmdpool
|
// VUID-vkCmdSetScissor-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1160,8 +1200,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::ScissorWithCount)?;
|
self.validate_pipeline_fixed_state(DynamicState::ScissorWithCount)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetScissorWithCount-commandBuffer-cmdpool
|
// VUID-vkCmdSetScissorWithCount-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1232,8 +1274,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetStencilCompareMask-faceMask-parameter
|
// VUID-vkCmdSetStencilCompareMask-faceMask-parameter
|
||||||
faces.validate_device(self.device())?;
|
faces.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetStencilCompareMask-commandBuffer-cmdpool
|
// VUID-vkCmdSetStencilCompareMask-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1294,8 +1338,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetStencilOp-compareOp-parameter
|
// VUID-vkCmdSetStencilOp-compareOp-parameter
|
||||||
compare_op.validate_device(self.device())?;
|
compare_op.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetStencilOp-commandBuffer-cmdpool
|
// VUID-vkCmdSetStencilOp-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1343,8 +1389,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetStencilReference-faceMask-parameter
|
// VUID-vkCmdSetStencilReference-faceMask-parameter
|
||||||
faces.validate_device(self.device())?;
|
faces.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetStencilReference-commandBuffer-cmdpool
|
// VUID-vkCmdSetStencilReference-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1374,8 +1422,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
fn validate_set_stencil_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
fn validate_set_stencil_test_enable(&self, _enable: bool) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::StencilTestEnable)?;
|
self.validate_pipeline_fixed_state(DynamicState::StencilTestEnable)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetStencilTestEnable-commandBuffer-cmdpool
|
// VUID-vkCmdSetStencilTestEnable-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1423,8 +1473,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdSetStencilWriteMask-faceMask-parameter
|
// VUID-vkCmdSetStencilWriteMask-faceMask-parameter
|
||||||
faces.validate_device(self.device())?;
|
faces.validate_device(self.device())?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetStencilWriteMask-commandBuffer-cmdpool
|
// VUID-vkCmdSetStencilWriteMask-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1463,8 +1515,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::Viewport)?;
|
self.validate_pipeline_fixed_state(DynamicState::Viewport)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetViewport-commandBuffer-cmdpool
|
// VUID-vkCmdSetViewport-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1539,8 +1593,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
) -> Result<(), SetDynamicStateError> {
|
) -> Result<(), SetDynamicStateError> {
|
||||||
self.validate_pipeline_fixed_state(DynamicState::ViewportWithCount)?;
|
self.validate_pipeline_fixed_state(DynamicState::ViewportWithCount)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdSetViewportWithCount-commandBuffer-cmdpool
|
// VUID-vkCmdSetViewportWithCount-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
return Err(SetDynamicStateError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,8 +86,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBlitImage2-commandBuffer-cmdpool
|
// VUID-vkCmdBlitImage2-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -586,8 +588,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdClearColorImage-commandBuffer-cmdpool
|
// VUID-vkCmdClearColorImage-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -734,8 +740,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdClearDepthStencilImage-commandBuffer-cmdpool
|
// VUID-vkCmdClearDepthStencilImage-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -890,8 +898,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdResolveImage2-commandBuffer-cmdpool
|
// VUID-vkCmdResolveImage2-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,8 +70,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate_dispatch(&self, group_counts: [u32; 3]) -> Result<(), PipelineExecutionError> {
|
fn validate_dispatch(&self, group_counts: [u32; 3]) -> Result<(), PipelineExecutionError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdDispatch-commandBuffer-cmdpool
|
// VUID-vkCmdDispatch-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_compute() {
|
if !queue_family_properties.queue_flags.compute {
|
||||||
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,8 +137,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
&self,
|
&self,
|
||||||
indirect_buffer: &dyn BufferAccess,
|
indirect_buffer: &dyn BufferAccess,
|
||||||
) -> Result<(), PipelineExecutionError> {
|
) -> Result<(), PipelineExecutionError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool
|
// VUID-vkCmdDispatchIndirect-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_compute() {
|
if !queue_family_properties.queue_flags.compute {
|
||||||
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
return Err(PipelineExecutionError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ use crate::{
|
|||||||
sys::UnsafeCommandBufferBuilder,
|
sys::UnsafeCommandBufferBuilder,
|
||||||
AutoCommandBufferBuilder,
|
AutoCommandBufferBuilder,
|
||||||
},
|
},
|
||||||
device::{physical::QueueFamily, DeviceOwned},
|
device::DeviceOwned,
|
||||||
query::{
|
query::{
|
||||||
QueriesRange, Query, QueryControlFlags, QueryPool, QueryResultElement, QueryResultFlags,
|
QueriesRange, Query, QueryControlFlags, QueryPool, QueryResultElement, QueryResultFlags,
|
||||||
QueryType,
|
QueryType,
|
||||||
@ -71,8 +71,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
query: u32,
|
query: u32,
|
||||||
flags: QueryControlFlags,
|
flags: QueryControlFlags,
|
||||||
) -> Result<(), QueryError> {
|
) -> Result<(), QueryError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +95,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
QueryType::Occlusion => {
|
QueryType::Occlusion => {
|
||||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||||
// // VUID-vkCmdBeginQuery-queryType-00803
|
// // VUID-vkCmdBeginQuery-queryType-00803
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,8 +114,9 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
// VUID-vkCmdBeginQuery-commandBuffer-cmdpool
|
||||||
// VUID-vkCmdBeginQuery-queryType-00804
|
// VUID-vkCmdBeginQuery-queryType-00804
|
||||||
// VUID-vkCmdBeginQuery-queryType-00805
|
// VUID-vkCmdBeginQuery-queryType-00805
|
||||||
if statistic_flags.is_compute() && !self.queue_family().supports_compute()
|
if statistic_flags.is_compute() && !queue_family_properties.queue_flags.compute
|
||||||
|| statistic_flags.is_graphics() && !self.queue_family().supports_graphics()
|
|| statistic_flags.is_graphics()
|
||||||
|
&& !queue_family_properties.queue_flags.graphics
|
||||||
{
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -165,8 +170,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn validate_end_query(&self, query_pool: &QueryPool, query: u32) -> Result<(), QueryError> {
|
fn validate_end_query(&self, query_pool: &QueryPool, query: u32) -> Result<(), QueryError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdEndQuery-commandBuffer-cmdpool
|
// VUID-vkCmdEndQuery-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +218,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
query: u32,
|
query: u32,
|
||||||
stage: PipelineStage,
|
stage: PipelineStage,
|
||||||
) -> Result<&mut Self, QueryError> {
|
) -> Result<&mut Self, QueryError> {
|
||||||
self.validate_write_timestamp(self.queue_family(), &query_pool, query, stage)?;
|
self.validate_write_timestamp(&query_pool, query, stage)?;
|
||||||
|
|
||||||
self.inner.write_timestamp(query_pool, query, stage);
|
self.inner.write_timestamp(query_pool, query, stage);
|
||||||
|
|
||||||
@ -218,15 +227,16 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
|
|
||||||
fn validate_write_timestamp(
|
fn validate_write_timestamp(
|
||||||
&self,
|
&self,
|
||||||
queue_family: QueueFamily,
|
|
||||||
query_pool: &QueryPool,
|
query_pool: &QueryPool,
|
||||||
query: u32,
|
query: u32,
|
||||||
stage: PipelineStage,
|
stage: PipelineStage,
|
||||||
) -> Result<(), QueryError> {
|
) -> Result<(), QueryError> {
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdWriteTimestamp-commandBuffer-cmdpool
|
// VUID-vkCmdWriteTimestamp-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -237,7 +247,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
assert_eq!(device, query_pool.device());
|
assert_eq!(device, query_pool.device());
|
||||||
|
|
||||||
// VUID-vkCmdWriteTimestamp-pipelineStage-04074
|
// VUID-vkCmdWriteTimestamp-pipelineStage-04074
|
||||||
if !queue_family.supports_stage(stage) {
|
if !queue_family_properties.supports_stage(stage) {
|
||||||
return Err(QueryError::StageNotSupported);
|
return Err(QueryError::StageNotSupported);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +286,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdWriteTimestamp-timestampValidBits-00829
|
// VUID-vkCmdWriteTimestamp-timestampValidBits-00829
|
||||||
if queue_family.timestamp_valid_bits().is_none() {
|
if queue_family_properties.timestamp_valid_bits.is_none() {
|
||||||
return Err(QueryError::NoTimestampValidBits);
|
return Err(QueryError::NoTimestampValidBits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,8 +356,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
D: ?Sized + TypedBufferAccess<Content = [T]>,
|
D: ?Sized + TypedBufferAccess<Content = [T]>,
|
||||||
T: QueryResultElement,
|
T: QueryResultElement,
|
||||||
{
|
{
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdCopyQueryPoolResults-commandBuffer-cmdpool
|
// VUID-vkCmdCopyQueryPoolResults-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,8 +445,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(QueryError::ForbiddenInsideRenderPass);
|
return Err(QueryError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdResetQueryPool-commandBuffer-cmdpool
|
// VUID-vkCmdResetQueryPool-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute()) {
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
|
{
|
||||||
return Err(QueryError::NotSupportedByQueueFamily);
|
return Err(QueryError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +101,10 @@ where
|
|||||||
// VUID-VkSubpassBeginInfo-contents-parameter
|
// VUID-VkSubpassBeginInfo-contents-parameter
|
||||||
contents.validate_device(device)?;
|
contents.validate_device(device)?;
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBeginRenderPass2-commandBuffer-cmdpool
|
// VUID-vkCmdBeginRenderPass2-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(RenderPassError::NotSupportedByQueueFamily);
|
return Err(RenderPassError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,7 +455,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdNextSubpass2-commandBuffer-cmdpool
|
// VUID-vkCmdNextSubpass2-commandBuffer-cmdpool
|
||||||
debug_assert!(self.queue_family().supports_graphics());
|
debug_assert!({
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
queue_family_properties.queue_flags.graphics
|
||||||
|
});
|
||||||
|
|
||||||
// VUID-vkCmdNextSubpass2-bufferlevel
|
// VUID-vkCmdNextSubpass2-bufferlevel
|
||||||
// Ensured by the type of the impl block
|
// Ensured by the type of the impl block
|
||||||
@ -509,7 +514,10 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdEndRenderPass2-commandBuffer-cmdpool
|
// VUID-vkCmdEndRenderPass2-commandBuffer-cmdpool
|
||||||
debug_assert!(self.queue_family().supports_graphics());
|
debug_assert!({
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
queue_family_properties.queue_flags.graphics
|
||||||
|
});
|
||||||
|
|
||||||
// VUID-vkCmdEndRenderPass2-bufferlevel
|
// VUID-vkCmdEndRenderPass2-bufferlevel
|
||||||
// Ensured by the type of the impl block
|
// Ensured by the type of the impl block
|
||||||
@ -675,8 +683,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdBeginRendering-commandBuffer-cmdpool
|
// VUID-vkCmdBeginRendering-commandBuffer-cmdpool
|
||||||
if !self.queue_family().supports_graphics() {
|
if !queue_family_properties.queue_flags.graphics {
|
||||||
return Err(RenderPassError::NotSupportedByQueueFamily);
|
return Err(RenderPassError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1228,7 +1238,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdEndRendering-commandBuffer-cmdpool
|
// VUID-vkCmdEndRendering-commandBuffer-cmdpool
|
||||||
debug_assert!(self.queue_family().supports_graphics());
|
debug_assert!({
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
queue_family_properties.queue_flags.graphics
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1476,7 +1489,10 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VUID-vkCmdClearAttachments-commandBuffer-cmdpool
|
// VUID-vkCmdClearAttachments-commandBuffer-cmdpool
|
||||||
debug_assert!(self.queue_family().supports_graphics());
|
debug_assert!({
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
queue_family_properties.queue_flags.graphics
|
||||||
|
});
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -114,10 +114,12 @@ where
|
|||||||
// VUID-vkCmdExecuteCommands-commonparent
|
// VUID-vkCmdExecuteCommands-commonparent
|
||||||
assert_eq!(self.device(), command_buffer.device());
|
assert_eq!(self.device(), command_buffer.device());
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdExecuteCommands-commandBuffer-cmdpool
|
// VUID-vkCmdExecuteCommands-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(ExecuteCommandsError::NotSupportedByQueueFamily);
|
return Err(ExecuteCommandsError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
@ -63,10 +63,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdCopyBuffer2-commandBuffer-cmdpool
|
// VUID-vkCmdCopyBuffer2-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -211,10 +213,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdCopyImage2-commandBuffer-cmdpool
|
// VUID-vkCmdCopyImage2-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -319,7 +323,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||||
[0, 0, 0] => None,
|
[0, 0, 0] => None,
|
||||||
min_image_transfer_granularity => {
|
min_image_transfer_granularity => {
|
||||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||||
@ -861,10 +865,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdCopyBufferToImage2-commandBuffer-cmdpool
|
// VUID-vkCmdCopyBufferToImage2-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -888,7 +894,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
let mut image_aspects = dst_image.format().aspects();
|
let mut image_aspects = dst_image.format().aspects();
|
||||||
|
|
||||||
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04477
|
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04477
|
||||||
if !self.queue_family().supports_graphics() && !image_aspects.color {
|
if !queue_family_properties.queue_flags.graphics && !image_aspects.color {
|
||||||
return Err(CopyError::DepthStencilNotSupportedByQueueFamily);
|
return Err(CopyError::DepthStencilNotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,7 +947,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||||
[0, 0, 0] => None,
|
[0, 0, 0] => None,
|
||||||
min_image_transfer_granularity => {
|
min_image_transfer_granularity => {
|
||||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||||
@ -1218,8 +1224,8 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
|
|
||||||
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04052
|
// VUID-VkCopyBufferToImageInfo2-commandBuffer-04052
|
||||||
// Make the alignment a multiple of 4.
|
// Make the alignment a multiple of 4.
|
||||||
if !(self.queue_family().supports_graphics()
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
if buffer_offset_alignment % 2 != 0 {
|
if buffer_offset_alignment % 2 != 0 {
|
||||||
buffer_offset_alignment *= 2;
|
buffer_offset_alignment *= 2;
|
||||||
@ -1290,10 +1296,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdCopyImageToBuffer2-commandBuffer-cmdpool
|
// VUID-vkCmdCopyImageToBuffer2-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -1365,7 +1373,7 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let extent_alignment = match self.queue_family().min_image_transfer_granularity() {
|
let extent_alignment = match queue_family_properties.min_image_transfer_granularity {
|
||||||
[0, 0, 0] => None,
|
[0, 0, 0] => None,
|
||||||
min_image_transfer_granularity => {
|
min_image_transfer_granularity => {
|
||||||
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
let granularity = move |block_extent: [u32; 3], is_multi_plane: bool| {
|
||||||
@ -1640,8 +1648,8 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
|
|
||||||
// VUID-VkCopyImageToBufferInfo2-commandBuffer-04052
|
// VUID-VkCopyImageToBufferInfo2-commandBuffer-04052
|
||||||
// Make the alignment a multiple of 4.
|
// Make the alignment a multiple of 4.
|
||||||
if !(self.queue_family().supports_graphics()
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
if buffer_offset_alignment % 2 != 0 {
|
if buffer_offset_alignment % 2 != 0 {
|
||||||
buffer_offset_alignment *= 2;
|
buffer_offset_alignment *= 2;
|
||||||
@ -1717,17 +1725,20 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
if device.api_version() >= Version::V1_1 || device.enabled_extensions().khr_maintenance1 {
|
if device.api_version() >= Version::V1_1 || device.enabled_extensions().khr_maintenance1 {
|
||||||
// VUID-vkCmdFillBuffer-commandBuffer-cmdpool
|
// VUID-vkCmdFillBuffer-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// VUID-vkCmdFillBuffer-commandBuffer-00030
|
// VUID-vkCmdFillBuffer-commandBuffer-00030
|
||||||
if !(self.queue_family().supports_graphics() || self.queue_family().supports_compute())
|
if !(queue_family_properties.queue_flags.graphics
|
||||||
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
@ -1833,10 +1844,12 @@ impl<L, P> AutoCommandBufferBuilder<L, P> {
|
|||||||
return Err(CopyError::ForbiddenInsideRenderPass);
|
return Err(CopyError::ForbiddenInsideRenderPass);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let queue_family_properties = self.queue_family_properties();
|
||||||
|
|
||||||
// VUID-vkCmdUpdateBuffer-commandBuffer-cmdpool
|
// VUID-vkCmdUpdateBuffer-commandBuffer-cmdpool
|
||||||
if !(self.queue_family().explicitly_supports_transfers()
|
if !(queue_family_properties.queue_flags.transfer
|
||||||
|| self.queue_family().supports_graphics()
|
|| queue_family_properties.queue_flags.graphics
|
||||||
|| self.queue_family().supports_compute())
|
|| queue_family_properties.queue_flags.compute)
|
||||||
{
|
{
|
||||||
return Err(CopyError::NotSupportedByQueueFamily);
|
return Err(CopyError::NotSupportedByQueueFamily);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
//! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return;
|
//! # let graphics_pipeline: std::sync::Arc<vulkano::pipeline::graphics::GraphicsPipeline> = return;
|
||||||
//! let cb = AutoCommandBufferBuilder::primary(
|
//! let cb = AutoCommandBufferBuilder::primary(
|
||||||
//! device.clone(),
|
//! device.clone(),
|
||||||
//! queue.family(),
|
//! queue.queue_family_index(),
|
||||||
//! CommandBufferUsage::MultipleSubmit
|
//! CommandBufferUsage::MultipleSubmit
|
||||||
//! ).unwrap()
|
//! ).unwrap()
|
||||||
//! .begin_render_pass(render_pass_begin_info, SubpassContents::Inline).unwrap()
|
//! .begin_render_pass(render_pass_begin_info, SubpassContents::Inline).unwrap()
|
||||||
|
@ -24,10 +24,7 @@ pub use self::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
use super::CommandBufferLevel;
|
use super::CommandBufferLevel;
|
||||||
use crate::{
|
use crate::{device::DeviceOwned, OomError};
|
||||||
device::{physical::QueueFamily, DeviceOwned},
|
|
||||||
OomError,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod standard;
|
pub mod standard;
|
||||||
mod sys;
|
mod sys;
|
||||||
@ -70,8 +67,8 @@ pub unsafe trait CommandPool: DeviceOwned {
|
|||||||
command_buffer_count: u32,
|
command_buffer_count: u32,
|
||||||
) -> Result<Self::Iter, OomError>;
|
) -> Result<Self::Iter, OomError>;
|
||||||
|
|
||||||
/// Returns the queue family that this pool targets.
|
/// Returns the index of the queue family that this pool targets.
|
||||||
fn queue_family(&self) -> QueueFamily;
|
fn queue_family_index(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A command buffer allocated from a pool and that can be recorded.
|
/// A command buffer allocated from a pool and that can be recorded.
|
||||||
@ -90,8 +87,8 @@ pub unsafe trait CommandPoolBuilderAlloc: DeviceOwned {
|
|||||||
/// Turns this builder into a command buffer that is pending execution.
|
/// Turns this builder into a command buffer that is pending execution.
|
||||||
fn into_alloc(self) -> Self::Alloc;
|
fn into_alloc(self) -> Self::Alloc;
|
||||||
|
|
||||||
/// Returns the queue family that the pool targets.
|
/// Returns the index of the queue family that the pool targets.
|
||||||
fn queue_family(&self) -> QueueFamily;
|
fn queue_family_index(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A command buffer allocated from a pool that has finished being recorded.
|
/// A command buffer allocated from a pool that has finished being recorded.
|
||||||
@ -104,6 +101,6 @@ pub unsafe trait CommandPoolAlloc: DeviceOwned + Send + Sync {
|
|||||||
/// Returns the internal object that contains the command buffer.
|
/// Returns the internal object that contains the command buffer.
|
||||||
fn inner(&self) -> &UnsafeCommandPoolAlloc;
|
fn inner(&self) -> &UnsafeCommandPoolAlloc;
|
||||||
|
|
||||||
/// Returns the queue family that the pool targets.
|
/// Returns the index of the queue family that the pool targets.
|
||||||
fn queue_family(&self) -> QueueFamily;
|
fn queue_family_index(&self) -> u32;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,8 @@ use super::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
command_buffer::CommandBufferLevel,
|
command_buffer::CommandBufferLevel,
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
OomError, VulkanObject,
|
OomError,
|
||||||
};
|
};
|
||||||
use crossbeam_queue::SegQueue;
|
use crossbeam_queue::SegQueue;
|
||||||
use std::{marker::PhantomData, mem::ManuallyDrop, ptr, sync::Arc, vec::IntoIter as VecIntoIter};
|
use std::{marker::PhantomData, mem::ManuallyDrop, ptr, sync::Arc, vec::IntoIter as VecIntoIter};
|
||||||
@ -45,17 +45,16 @@ impl StandardCommandPool {
|
|||||||
/// - Panics if the device and the queue family don't belong to the same physical device.
|
/// - Panics if the device and the queue family don't belong to the same physical device.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
queue_family: QueueFamily,
|
queue_family_index: u32,
|
||||||
) -> Result<StandardCommandPool, OomError> {
|
) -> Result<StandardCommandPool, OomError> {
|
||||||
assert_eq!(
|
assert!(
|
||||||
device.physical_device().internal_object(),
|
queue_family_index < device.physical_device().queue_family_properties().len() as u32
|
||||||
queue_family.physical_device().internal_object()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
let inner = UnsafeCommandPool::new(
|
let inner = UnsafeCommandPool::new(
|
||||||
device,
|
device,
|
||||||
UnsafeCommandPoolCreateInfo {
|
UnsafeCommandPoolCreateInfo {
|
||||||
queue_family_index: queue_family.id(),
|
queue_family_index,
|
||||||
reset_command_buffer: true,
|
reset_command_buffer: true,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -135,8 +134,8 @@ unsafe impl CommandPool for Arc<StandardCommandPool> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn queue_family(&self) -> QueueFamily {
|
fn queue_family_index(&self) -> u32 {
|
||||||
self.inner.queue_family()
|
self.inner.queue_family_index()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,8 +169,8 @@ unsafe impl CommandPoolBuilderAlloc for StandardCommandPoolBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn queue_family(&self) -> QueueFamily {
|
fn queue_family_index(&self) -> u32 {
|
||||||
self.inner.queue_family()
|
self.inner.queue_family_index()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,8 +199,8 @@ unsafe impl CommandPoolAlloc for StandardCommandPoolAlloc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn queue_family(&self) -> QueueFamily {
|
fn queue_family_index(&self) -> u32 {
|
||||||
self.pool.queue_family()
|
self.pool.queue_family_index()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +241,7 @@ mod tests {
|
|||||||
let (device, queue) = gfx_dev_and_queue!();
|
let (device, queue) = gfx_dev_and_queue!();
|
||||||
|
|
||||||
device
|
device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
let cb = pool
|
let cb = pool
|
||||||
.allocate(CommandBufferLevel::Primary, 1)
|
.allocate(CommandBufferLevel::Primary, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
@ -269,7 +268,7 @@ mod tests {
|
|||||||
let (device, queue) = (device, queue);
|
let (device, queue) = (device, queue);
|
||||||
move || {
|
move || {
|
||||||
device
|
device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next()
|
.next()
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
command_buffer::CommandBufferLevel,
|
command_buffer::CommandBufferLevel,
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
OomError, RequiresOneOf, Version, VulkanError, VulkanObject,
|
OomError, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
@ -111,14 +111,10 @@ impl UnsafeCommandPool {
|
|||||||
} = create_info;
|
} = create_info;
|
||||||
|
|
||||||
// VUID-vkCreateCommandPool-queueFamilyIndex-01937
|
// VUID-vkCreateCommandPool-queueFamilyIndex-01937
|
||||||
if device
|
if queue_family_index >= device.physical_device().queue_family_properties().len() as u32 {
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(queue_family_index)
|
|
||||||
.is_none()
|
|
||||||
{
|
|
||||||
return Err(UnsafeCommandPoolCreationError::QueueFamilyIndexOutOfRange {
|
return Err(UnsafeCommandPoolCreationError::QueueFamilyIndexOutOfRange {
|
||||||
queue_family_index,
|
queue_family_index,
|
||||||
queue_family_count: device.physical_device().queue_families().len() as u32,
|
queue_family_count: device.physical_device().queue_family_properties().len() as u32,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,11 +304,8 @@ impl UnsafeCommandPool {
|
|||||||
|
|
||||||
/// Returns the queue family on which command buffers of this pool can be executed.
|
/// Returns the queue family on which command buffers of this pool can be executed.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn queue_family(&self) -> QueueFamily {
|
pub fn queue_family_index(&self) -> u32 {
|
||||||
self.device
|
self.queue_family_index
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(self.queue_family_index)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +357,7 @@ impl Hash for UnsafeCommandPool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Error that can happen when creating an `UnsafeCommandPool`.
|
/// Error that can happen when creating an `UnsafeCommandPool`.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum UnsafeCommandPoolCreationError {
|
pub enum UnsafeCommandPoolCreationError {
|
||||||
/// Not enough memory.
|
/// Not enough memory.
|
||||||
OomError(OomError),
|
OomError(OomError),
|
||||||
@ -576,7 +569,7 @@ mod tests {
|
|||||||
let _ = UnsafeCommandPool::new(
|
let _ = UnsafeCommandPool::new(
|
||||||
device,
|
device,
|
||||||
UnsafeCommandPoolCreateInfo {
|
UnsafeCommandPoolCreateInfo {
|
||||||
queue_family_index: queue.family().id(),
|
queue_family_index: queue.queue_family_index(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -589,12 +582,12 @@ mod tests {
|
|||||||
let pool = UnsafeCommandPool::new(
|
let pool = UnsafeCommandPool::new(
|
||||||
device,
|
device,
|
||||||
UnsafeCommandPoolCreateInfo {
|
UnsafeCommandPoolCreateInfo {
|
||||||
queue_family_index: queue.family().id(),
|
queue_family_index: queue.queue_family_index(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(pool.queue_family().id(), queue.family().id());
|
assert_eq!(pool.queue_family_index(), queue.queue_family_index());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -618,7 +611,7 @@ mod tests {
|
|||||||
let pool = UnsafeCommandPool::new(
|
let pool = UnsafeCommandPool::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
UnsafeCommandPoolCreateInfo {
|
UnsafeCommandPoolCreateInfo {
|
||||||
queue_family_index: queue.family().id(),
|
queue_family_index: queue.queue_family_index(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -660,7 +653,7 @@ mod tests {
|
|||||||
let pool = UnsafeCommandPool::new(
|
let pool = UnsafeCommandPool::new(
|
||||||
device,
|
device,
|
||||||
UnsafeCommandPoolCreateInfo {
|
UnsafeCommandPoolCreateInfo {
|
||||||
queue_family_index: queue.family().id(),
|
queue_family_index: queue.queue_family_index(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -136,7 +136,12 @@ impl<'a> SubmitBindSparseBuilder<'a> {
|
|||||||
/// Submits the command. Calls `vkQueueBindSparse`.
|
/// Submits the command. Calls `vkQueueBindSparse`.
|
||||||
pub fn submit(self, queue: &Queue) -> Result<(), SubmitBindSparseError> {
|
pub fn submit(self, queue: &Queue) -> Result<(), SubmitBindSparseError> {
|
||||||
unsafe {
|
unsafe {
|
||||||
debug_assert!(queue.family().supports_sparse_binding());
|
debug_assert!(
|
||||||
|
queue.device().physical_device().queue_family_properties()
|
||||||
|
[queue.queue_family_index() as usize]
|
||||||
|
.queue_flags
|
||||||
|
.sparse_binding
|
||||||
|
);
|
||||||
|
|
||||||
let fns = queue.device().fns();
|
let fns = queue.device().fns();
|
||||||
let queue = queue.internal_object_guard();
|
let queue = queue.internal_object_guard();
|
||||||
|
@ -553,7 +553,7 @@ mod tests {
|
|||||||
let (device, queue) = gfx_dev_and_queue!();
|
let (device, queue) = gfx_dev_and_queue!();
|
||||||
|
|
||||||
let pool_builder_alloc = device
|
let pool_builder_alloc = device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next()
|
.next()
|
||||||
@ -598,7 +598,7 @@ mod tests {
|
|||||||
.map(|_| {
|
.map(|_| {
|
||||||
let mut builder = AutoCommandBufferBuilder::secondary(
|
let mut builder = AutoCommandBufferBuilder::secondary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::SimultaneousUse,
|
CommandBufferUsage::SimultaneousUse,
|
||||||
Default::default(),
|
Default::default(),
|
||||||
)
|
)
|
||||||
@ -614,7 +614,7 @@ mod tests {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
let allocs = device
|
let allocs = device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
pool.allocate(CommandBufferLevel::Primary, 2)
|
pool.allocate(CommandBufferLevel::Primary, 2)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@ -676,7 +676,7 @@ mod tests {
|
|||||||
let (device, queue) = gfx_dev_and_queue!();
|
let (device, queue) = gfx_dev_and_queue!();
|
||||||
|
|
||||||
let pool_builder_alloc = device
|
let pool_builder_alloc = device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next()
|
.next()
|
||||||
@ -717,7 +717,7 @@ mod tests {
|
|||||||
let (device, queue) = gfx_dev_and_queue!();
|
let (device, queue) = gfx_dev_and_queue!();
|
||||||
|
|
||||||
let pool_builder_alloc = device
|
let pool_builder_alloc = device
|
||||||
.with_standard_command_pool(queue.family(), |pool| {
|
.with_standard_command_pool(queue.queue_family_index(), |pool| {
|
||||||
pool.allocate(CommandBufferLevel::Primary, 1)
|
pool.allocate(CommandBufferLevel::Primary, 1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.next()
|
.next()
|
||||||
|
@ -29,11 +29,13 @@
|
|||||||
//!
|
//!
|
||||||
//! // We just choose the first physical device. In a real application you would choose depending
|
//! // We just choose the first physical device. In a real application you would choose depending
|
||||||
//! // on the capabilities of the physical device and the user's preferences.
|
//! // on the capabilities of the physical device and the user's preferences.
|
||||||
//! let physical_device = PhysicalDevice::enumerate(&instance).next().expect("No physical device");
|
//! let physical_device = instance
|
||||||
|
//! .enumerate_physical_devices()
|
||||||
|
//! .unwrap_or_else(|err| panic!("Couldn't enumerate physical devices: {:?}", err))
|
||||||
|
//! .next().expect("No physical device");
|
||||||
//!
|
//!
|
||||||
//! // Here is the device-creating code.
|
//! // Here is the device-creating code.
|
||||||
//! let device = {
|
//! let device = {
|
||||||
//! let queue_family = physical_device.queue_families().next().unwrap();
|
|
||||||
//! let features = Features::empty();
|
//! let features = Features::empty();
|
||||||
//! let extensions = DeviceExtensions::empty();
|
//! let extensions = DeviceExtensions::empty();
|
||||||
//!
|
//!
|
||||||
@ -42,7 +44,10 @@
|
|||||||
//! DeviceCreateInfo {
|
//! DeviceCreateInfo {
|
||||||
//! enabled_extensions: extensions,
|
//! enabled_extensions: extensions,
|
||||||
//! enabled_features: features,
|
//! enabled_features: features,
|
||||||
//! queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
//! queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
//! queue_family_index: 0,
|
||||||
|
//! ..Default::default()
|
||||||
|
//! }],
|
||||||
//! ..Default::default()
|
//! ..Default::default()
|
||||||
//! },
|
//! },
|
||||||
//! ) {
|
//! ) {
|
||||||
@ -96,7 +101,7 @@
|
|||||||
//!
|
//!
|
||||||
//! TODO: write
|
//! TODO: write
|
||||||
|
|
||||||
use self::physical::{PhysicalDevice, QueueFamily};
|
use self::physical::PhysicalDevice;
|
||||||
pub(crate) use self::{features::FeaturesFfi, properties::PropertiesFfi};
|
pub(crate) use self::{features::FeaturesFfi, properties::PropertiesFfi};
|
||||||
pub use self::{
|
pub use self::{
|
||||||
features::{FeatureRestriction, FeatureRestrictionError, Features},
|
features::{FeatureRestriction, FeatureRestrictionError, Features},
|
||||||
@ -142,8 +147,7 @@ pub(crate) mod properties;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Device {
|
pub struct Device {
|
||||||
handle: ash::vk::Device,
|
handle: ash::vk::Device,
|
||||||
instance: Arc<Instance>,
|
physical_device: Arc<PhysicalDevice>,
|
||||||
physical_device: usize,
|
|
||||||
|
|
||||||
// The highest version that is supported for this device.
|
// The highest version that is supported for this device.
|
||||||
// This is the minimum of Instance::max_api_version and PhysicalDevice::api_version.
|
// This is the minimum of Instance::max_api_version and PhysicalDevice::api_version.
|
||||||
@ -153,7 +157,7 @@ pub struct Device {
|
|||||||
standard_memory_pool: OnceCell<Arc<StandardMemoryPool>>,
|
standard_memory_pool: OnceCell<Arc<StandardMemoryPool>>,
|
||||||
enabled_extensions: DeviceExtensions,
|
enabled_extensions: DeviceExtensions,
|
||||||
enabled_features: Features,
|
enabled_features: Features,
|
||||||
active_queue_families: SmallVec<[u32; 2]>,
|
active_queue_family_indices: SmallVec<[u32; 2]>,
|
||||||
allocation_count: Mutex<u32>,
|
allocation_count: Mutex<u32>,
|
||||||
fence_pool: Mutex<Vec<ash::vk::Fence>>,
|
fence_pool: Mutex<Vec<ash::vk::Fence>>,
|
||||||
semaphore_pool: Mutex<Vec<ash::vk::Semaphore>>,
|
semaphore_pool: Mutex<Vec<ash::vk::Semaphore>>,
|
||||||
@ -178,7 +182,7 @@ impl Device {
|
|||||||
/// - Panics if `create_info.queues` contains an element where `queues` contains a value that is
|
/// - Panics if `create_info.queues` contains an element where `queues` contains a value that is
|
||||||
/// not between 0.0 and 1.0 inclusive.
|
/// not between 0.0 and 1.0 inclusive.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
physical_device: PhysicalDevice,
|
physical_device: Arc<PhysicalDevice>,
|
||||||
create_info: DeviceCreateInfo,
|
create_info: DeviceCreateInfo,
|
||||||
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), DeviceCreationError> {
|
) -> Result<(Arc<Device>, impl ExactSizeIterator<Item = Arc<Queue>>), DeviceCreationError> {
|
||||||
let DeviceCreateInfo {
|
let DeviceCreateInfo {
|
||||||
@ -197,7 +201,7 @@ impl Device {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct QueueToGet {
|
struct QueueToGet {
|
||||||
family: u32,
|
queue_family_index: u32,
|
||||||
id: u32,
|
id: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,26 +210,27 @@ impl Device {
|
|||||||
|
|
||||||
let mut queue_create_infos_vk: SmallVec<[_; 2]> =
|
let mut queue_create_infos_vk: SmallVec<[_; 2]> =
|
||||||
SmallVec::with_capacity(queue_create_infos.len());
|
SmallVec::with_capacity(queue_create_infos.len());
|
||||||
let mut active_queue_families: SmallVec<[_; 2]> =
|
let mut active_queue_family_indices: SmallVec<[_; 2]> =
|
||||||
SmallVec::with_capacity(queue_create_infos.len());
|
SmallVec::with_capacity(queue_create_infos.len());
|
||||||
let mut queues_to_get: 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 {
|
for queue_create_info in &queue_create_infos {
|
||||||
family,
|
let &QueueCreateInfo {
|
||||||
queues,
|
queue_family_index,
|
||||||
_ne: _,
|
ref queues,
|
||||||
} in &queue_create_infos
|
_ne: _,
|
||||||
{
|
} = queue_create_info;
|
||||||
assert_eq!(
|
|
||||||
family.physical_device().internal_object(),
|
// VUID-VkDeviceQueueCreateInfo-queueFamilyIndex-00381
|
||||||
physical_device.internal_object()
|
// TODO: return error instead of panicking?
|
||||||
);
|
let queue_family_properties =
|
||||||
|
&physical_device.queue_family_properties()[queue_family_index as usize];
|
||||||
|
|
||||||
// VUID-VkDeviceCreateInfo-queueFamilyIndex-02802
|
// VUID-VkDeviceCreateInfo-queueFamilyIndex-02802
|
||||||
assert!(
|
assert!(
|
||||||
queue_create_infos
|
queue_create_infos
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|qc2| qc2.family == *family)
|
.filter(|qc2| qc2.queue_family_index == queue_family_index)
|
||||||
.count()
|
.count()
|
||||||
== 1
|
== 1
|
||||||
);
|
);
|
||||||
@ -238,24 +243,26 @@ impl Device {
|
|||||||
.iter()
|
.iter()
|
||||||
.all(|&priority| (0.0..=1.0).contains(&priority)));
|
.all(|&priority| (0.0..=1.0).contains(&priority)));
|
||||||
|
|
||||||
if queues.len() > family.queues_count() {
|
if queues.len() > queue_family_properties.queue_count as usize {
|
||||||
return Err(DeviceCreationError::TooManyQueuesForFamily);
|
return Err(DeviceCreationError::TooManyQueuesForFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
let family = family.id();
|
|
||||||
queue_create_infos_vk.push(ash::vk::DeviceQueueCreateInfo {
|
queue_create_infos_vk.push(ash::vk::DeviceQueueCreateInfo {
|
||||||
flags: ash::vk::DeviceQueueCreateFlags::empty(),
|
flags: ash::vk::DeviceQueueCreateFlags::empty(),
|
||||||
queue_family_index: family,
|
queue_family_index,
|
||||||
queue_count: queues.len() as u32,
|
queue_count: queues.len() as u32,
|
||||||
p_queue_priorities: queues.as_ptr(), // borrows from queue_create
|
p_queue_priorities: queues.as_ptr(), // borrows from queue_create
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
active_queue_families.push(family);
|
active_queue_family_indices.push(queue_family_index);
|
||||||
queues_to_get.extend((0..queues.len() as u32).map(move |id| QueueToGet { family, id }));
|
queues_to_get.extend((0..queues.len() as u32).map(move |id| QueueToGet {
|
||||||
|
queue_family_index,
|
||||||
|
id,
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
active_queue_families.sort_unstable();
|
active_queue_family_indices.sort_unstable();
|
||||||
active_queue_families.dedup();
|
active_queue_family_indices.dedup();
|
||||||
let supported_extensions = physical_device.supported_extensions();
|
let supported_extensions = physical_device.supported_extensions();
|
||||||
|
|
||||||
if supported_extensions.khr_portability_subset {
|
if supported_extensions.khr_portability_subset {
|
||||||
@ -404,14 +411,13 @@ impl Device {
|
|||||||
|
|
||||||
let device = Arc::new(Device {
|
let device = Arc::new(Device {
|
||||||
handle,
|
handle,
|
||||||
instance: physical_device.instance().clone(),
|
physical_device,
|
||||||
physical_device: physical_device.index(),
|
|
||||||
api_version,
|
api_version,
|
||||||
fns,
|
fns,
|
||||||
standard_memory_pool: OnceCell::new(),
|
standard_memory_pool: OnceCell::new(),
|
||||||
enabled_extensions,
|
enabled_extensions,
|
||||||
enabled_features,
|
enabled_features,
|
||||||
active_queue_families,
|
active_queue_family_indices,
|
||||||
allocation_count: Mutex::new(0),
|
allocation_count: Mutex::new(0),
|
||||||
fence_pool: Mutex::new(Vec::new()),
|
fence_pool: Mutex::new(Vec::new()),
|
||||||
semaphore_pool: Mutex::new(Vec::new()),
|
semaphore_pool: Mutex::new(Vec::new()),
|
||||||
@ -421,20 +427,28 @@ impl Device {
|
|||||||
// Iterator to return the queues
|
// Iterator to return the queues
|
||||||
let queues_iter = {
|
let queues_iter = {
|
||||||
let device = device.clone();
|
let device = device.clone();
|
||||||
queues_to_get
|
queues_to_get.into_iter().map(
|
||||||
.into_iter()
|
move |QueueToGet {
|
||||||
.map(move |QueueToGet { family, id }| unsafe {
|
queue_family_index,
|
||||||
|
id,
|
||||||
|
}| unsafe {
|
||||||
let fns = device.fns();
|
let fns = device.fns();
|
||||||
let mut output = MaybeUninit::uninit();
|
let mut output = MaybeUninit::uninit();
|
||||||
(fns.v1_0.get_device_queue)(handle, family, id, output.as_mut_ptr());
|
(fns.v1_0.get_device_queue)(
|
||||||
|
handle,
|
||||||
|
queue_family_index,
|
||||||
|
id,
|
||||||
|
output.as_mut_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
Arc::new(Queue {
|
Arc::new(Queue {
|
||||||
handle: Mutex::new(output.assume_init()),
|
handle: Mutex::new(output.assume_init()),
|
||||||
device: device.clone(),
|
device: device.clone(),
|
||||||
family,
|
queue_family_index,
|
||||||
id,
|
id,
|
||||||
})
|
})
|
||||||
})
|
},
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((device, queues_iter))
|
Ok((device, queues_iter))
|
||||||
@ -456,47 +470,22 @@ impl Device {
|
|||||||
&self.fns
|
&self.fns
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits until all work on this device has finished. You should never need to call
|
/// Returns the physical device that was used to create this device.
|
||||||
/// this function, but it can be useful for debugging or benchmarking purposes.
|
#[inline]
|
||||||
///
|
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||||
/// > **Note**: This is the Vulkan equivalent of OpenGL's `glFinish`.
|
&self.physical_device
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// This function is not thread-safe. You must not submit anything to any of the queue
|
|
||||||
/// of the device (either explicitly or implicitly, for example with a future's destructor)
|
|
||||||
/// while this function is waiting.
|
|
||||||
///
|
|
||||||
pub unsafe fn wait(&self) -> Result<(), OomError> {
|
|
||||||
let fns = self.fns();
|
|
||||||
(fns.v1_0.device_wait_idle)(self.handle)
|
|
||||||
.result()
|
|
||||||
.map_err(VulkanError::from)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the instance used to create this device.
|
/// Returns the instance used to create this device.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn instance(&self) -> &Arc<Instance> {
|
pub fn instance(&self) -> &Arc<Instance> {
|
||||||
&self.instance
|
self.physical_device.instance()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the physical device that was used to create this device.
|
/// Returns the queue family indices that this device uses.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn physical_device(&self) -> PhysicalDevice {
|
pub fn active_queue_family_indices(&self) -> &[u32] {
|
||||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
&self.active_queue_family_indices
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns an iterator to the list of queues families that this device uses.
|
|
||||||
///
|
|
||||||
/// > **Note**: Will return `-> impl ExactSizeIterator<Item = QueueFamily>` in the future.
|
|
||||||
// TODO: ^
|
|
||||||
#[inline]
|
|
||||||
pub fn active_queue_families(&self) -> impl ExactSizeIterator<Item = QueueFamily> {
|
|
||||||
let physical_device = self.physical_device();
|
|
||||||
self.active_queue_families
|
|
||||||
.iter()
|
|
||||||
.map(move |&id| physical_device.queue_family_by_id(id).unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the extensions that have been enabled on the device.
|
/// Returns the extensions that have been enabled on the device.
|
||||||
@ -561,7 +550,7 @@ impl Device {
|
|||||||
/// - Panics if called again from within the callback.
|
/// - Panics if called again from within the callback.
|
||||||
pub fn with_standard_command_pool<T>(
|
pub fn with_standard_command_pool<T>(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
queue_family: QueueFamily,
|
queue_family_index: u32,
|
||||||
f: impl FnOnce(&Arc<StandardCommandPool>) -> T,
|
f: impl FnOnce(&Arc<StandardCommandPool>) -> T,
|
||||||
) -> Result<T, OomError> {
|
) -> Result<T, OomError> {
|
||||||
thread_local! {
|
thread_local! {
|
||||||
@ -571,11 +560,11 @@ impl Device {
|
|||||||
|
|
||||||
TLS.with(|tls| {
|
TLS.with(|tls| {
|
||||||
let mut tls = tls.borrow_mut();
|
let mut tls = tls.borrow_mut();
|
||||||
let pool = match tls.entry((self.internal_object(), queue_family.id())) {
|
let pool = match tls.entry((self.internal_object(), queue_family_index)) {
|
||||||
Entry::Occupied(entry) => entry.into_mut(),
|
Entry::Occupied(entry) => entry.into_mut(),
|
||||||
Entry::Vacant(entry) => entry.insert(Arc::new(StandardCommandPool::new(
|
Entry::Vacant(entry) => entry.insert(Arc::new(StandardCommandPool::new(
|
||||||
self.clone(),
|
self.clone(),
|
||||||
queue_family,
|
queue_family_index,
|
||||||
)?)),
|
)?)),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -680,7 +669,7 @@ impl Device {
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let fns = self.instance.fns();
|
let fns = self.instance().fns();
|
||||||
(fns.ext_debug_utils.set_debug_utils_object_name_ext)(self.handle, &info)
|
(fns.ext_debug_utils.set_debug_utils_object_name_ext)(self.handle, &info)
|
||||||
.result()
|
.result()
|
||||||
.map_err(VulkanError::from)?;
|
.map_err(VulkanError::from)?;
|
||||||
@ -688,6 +677,25 @@ impl Device {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Waits until all work on this device has finished. You should never need to call
|
||||||
|
/// this function, but it can be useful for debugging or benchmarking purposes.
|
||||||
|
///
|
||||||
|
/// > **Note**: This is the Vulkan equivalent of OpenGL's `glFinish`.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
///
|
||||||
|
/// This function is not thread-safe. You must not submit anything to any of the queue
|
||||||
|
/// of the device (either explicitly or implicitly, for example with a future's destructor)
|
||||||
|
/// while this function is waiting.
|
||||||
|
///
|
||||||
|
pub unsafe fn wait(&self) -> Result<(), OomError> {
|
||||||
|
let fns = self.fns();
|
||||||
|
(fns.v1_0.device_wait_idle)(self.handle)
|
||||||
|
.result()
|
||||||
|
.map_err(VulkanError::from)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Device {
|
impl Drop for Device {
|
||||||
@ -722,7 +730,7 @@ unsafe impl VulkanObject for Device {
|
|||||||
impl PartialEq for Device {
|
impl PartialEq for Device {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.handle == other.handle && self.instance == other.instance
|
self.handle == other.handle && self.physical_device == other.physical_device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -732,7 +740,7 @@ impl Hash for Device {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.handle.hash(state);
|
self.handle.hash(state);
|
||||||
self.instance.hash(state);
|
self.physical_device.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,7 +848,7 @@ impl From<FeatureRestrictionError> for DeviceCreationError {
|
|||||||
|
|
||||||
/// Parameters to create a new `Device`.
|
/// Parameters to create a new `Device`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct DeviceCreateInfo<'qf> {
|
pub struct DeviceCreateInfo {
|
||||||
/// The extensions to enable on the device.
|
/// The extensions to enable on the device.
|
||||||
///
|
///
|
||||||
/// The default value is [`DeviceExtensions::empty()`].
|
/// The default value is [`DeviceExtensions::empty()`].
|
||||||
@ -854,12 +862,12 @@ pub struct DeviceCreateInfo<'qf> {
|
|||||||
/// The queues to create for the device.
|
/// The queues to create for the device.
|
||||||
///
|
///
|
||||||
/// The default value is empty, which must be overridden.
|
/// The default value is empty, which must be overridden.
|
||||||
pub queue_create_infos: Vec<QueueCreateInfo<'qf>>,
|
pub queue_create_infos: Vec<QueueCreateInfo>,
|
||||||
|
|
||||||
pub _ne: crate::NonExhaustive,
|
pub _ne: crate::NonExhaustive,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DeviceCreateInfo<'static> {
|
impl Default for DeviceCreateInfo {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@ -873,9 +881,11 @@ impl Default for DeviceCreateInfo<'static> {
|
|||||||
|
|
||||||
/// Parameters to create queues in a new `Device`.
|
/// Parameters to create queues in a new `Device`.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct QueueCreateInfo<'qf> {
|
pub struct QueueCreateInfo {
|
||||||
/// The queue family to create queues for.
|
/// The index of the queue family to create queues for.
|
||||||
pub family: QueueFamily<'qf>,
|
///
|
||||||
|
/// The default value is `0`.
|
||||||
|
pub queue_family_index: u32,
|
||||||
|
|
||||||
/// The queues to create for the given queue family, each with a relative priority.
|
/// The queues to create for the given queue family, each with a relative priority.
|
||||||
///
|
///
|
||||||
@ -890,12 +900,11 @@ pub struct QueueCreateInfo<'qf> {
|
|||||||
pub _ne: crate::NonExhaustive,
|
pub _ne: crate::NonExhaustive,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'qf> QueueCreateInfo<'qf> {
|
impl Default for QueueCreateInfo {
|
||||||
/// Returns a `QueueCreateInfo` with the given queue family.
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn family(family: QueueFamily) -> QueueCreateInfo {
|
fn default() -> Self {
|
||||||
QueueCreateInfo {
|
Self {
|
||||||
family,
|
queue_family_index: 0,
|
||||||
queues: vec![0.5],
|
queues: vec![0.5],
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
}
|
}
|
||||||
@ -1011,7 +1020,7 @@ impl From<RequirementNotMet> for MemoryFdPropertiesError {
|
|||||||
pub struct Queue {
|
pub struct Queue {
|
||||||
handle: Mutex<ash::vk::Queue>,
|
handle: Mutex<ash::vk::Queue>,
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
family: u32,
|
queue_family_index: u32,
|
||||||
id: u32, // id within family
|
id: u32, // id within family
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1022,16 +1031,13 @@ impl Queue {
|
|||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the family this queue belongs to.
|
/// Returns the queue family that this queue belongs to.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn family(&self) -> QueueFamily {
|
pub fn queue_family_index(&self) -> u32 {
|
||||||
self.device
|
self.queue_family_index
|
||||||
.physical_device()
|
|
||||||
.queue_family_by_id(self.family)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of this queue within its family.
|
/// Returns the index of this queue within its queue family.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn id_within_family(&self) -> u32 {
|
pub fn id_within_family(&self) -> u32 {
|
||||||
self.id
|
self.id
|
||||||
@ -1224,7 +1230,9 @@ unsafe impl DeviceOwned for Queue {
|
|||||||
|
|
||||||
impl PartialEq for Queue {
|
impl PartialEq for Queue {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self.id == other.id && self.family == other.family && self.device == other.device
|
self.id == other.id
|
||||||
|
&& self.queue_family_index == other.queue_family_index
|
||||||
|
&& self.device == other.device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1234,7 +1242,7 @@ impl Hash for Queue {
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
self.id.hash(state);
|
self.id.hash(state);
|
||||||
self.family.hash(state);
|
self.queue_family_index.hash(state);
|
||||||
self.device.hash(state);
|
self.device.hash(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1269,8 +1277,8 @@ impl Display for DebugUtilsError {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::device::{
|
use crate::device::{
|
||||||
physical::PhysicalDevice, Device, DeviceCreateInfo, DeviceCreationError,
|
Device, DeviceCreateInfo, DeviceCreationError, FeatureRestriction, FeatureRestrictionError,
|
||||||
FeatureRestriction, FeatureRestrictionError, Features, QueueCreateInfo,
|
Features, QueueCreateInfo,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -1283,20 +1291,25 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn too_many_queues() {
|
fn too_many_queues() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let family = physical.queue_families().next().unwrap();
|
let queue_family_index = 0;
|
||||||
let _queues = (0..family.queues_count() + 1).map(|_| (family, 1.0));
|
let queue_family_properties =
|
||||||
|
&physical_device.queue_family_properties()[queue_family_index as usize];
|
||||||
|
let queues = (0..queue_family_properties.queue_count + 1)
|
||||||
|
.map(|_| (0.5))
|
||||||
|
.collect();
|
||||||
|
|
||||||
match Device::new(
|
match Device::new(
|
||||||
physical,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
queue_create_infos: vec![QueueCreateInfo {
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
queues: (0..family.queues_count() + 1).map(|_| (0.5)).collect(),
|
queue_family_index,
|
||||||
..QueueCreateInfo::family(family)
|
queues,
|
||||||
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -1307,26 +1320,27 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unsupposed_features() {
|
fn unsupported_features() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let family = physical.queue_families().next().unwrap();
|
|
||||||
|
|
||||||
let features = Features::all();
|
let features = Features::all();
|
||||||
// In the unlikely situation where the device supports everything, we ignore the test.
|
// In the unlikely situation where the device supports everything, we ignore the test.
|
||||||
if physical.supported_features().contains(&features) {
|
if physical_device.supported_features().contains(&features) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
match Device::new(
|
match Device::new(
|
||||||
physical,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
enabled_features: features,
|
enabled_features: features,
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index: 0,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@ -1341,20 +1355,19 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn priority_out_of_range() {
|
fn priority_out_of_range() {
|
||||||
let instance = instance!();
|
let instance = instance!();
|
||||||
let physical = match PhysicalDevice::enumerate(&instance).next() {
|
let physical_device = match instance.enumerate_physical_devices().unwrap().next() {
|
||||||
Some(p) => p,
|
Some(p) => p,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let family = physical.queue_families().next().unwrap();
|
|
||||||
|
|
||||||
assert_should_panic!({
|
assert_should_panic!({
|
||||||
Device::new(
|
Device::new(
|
||||||
physical,
|
physical_device.clone(),
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
queue_create_infos: vec![QueueCreateInfo {
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index: 0,
|
||||||
queues: vec![1.4],
|
queues: vec![1.4],
|
||||||
..QueueCreateInfo::family(family)
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@ -1363,11 +1376,12 @@ mod tests {
|
|||||||
|
|
||||||
assert_should_panic!({
|
assert_should_panic!({
|
||||||
Device::new(
|
Device::new(
|
||||||
physical,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
queue_create_infos: vec![QueueCreateInfo {
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index: 0,
|
||||||
queues: vec![-0.2],
|
queues: vec![-0.2],
|
||||||
..QueueCreateInfo::family(family)
|
..Default::default()
|
||||||
}],
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -443,7 +443,7 @@ impl AttachmentImage {
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
Some(DedicatedAllocation::Image(&image)),
|
Some(DedicatedAllocation::Image(&image)),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -523,7 +523,7 @@ impl AttachmentImage {
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
DedicatedAllocation::Image(&image),
|
DedicatedAllocation::Image(&image),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
|
@ -19,7 +19,7 @@ use crate::{
|
|||||||
CommandBufferUsage, CopyBufferToImageInfo, ImageBlit, PrimaryAutoCommandBuffer,
|
CommandBufferUsage, CopyBufferToImageInfo, ImageBlit, PrimaryAutoCommandBuffer,
|
||||||
PrimaryCommandBuffer,
|
PrimaryCommandBuffer,
|
||||||
},
|
},
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
device::{Device, DeviceOwned, Queue},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::sys::UnsafeImageCreateInfo,
|
image::sys::UnsafeImageCreateInfo,
|
||||||
memory::{
|
memory::{
|
||||||
@ -101,38 +101,31 @@ fn generate_mipmaps<L>(
|
|||||||
impl ImmutableImage {
|
impl ImmutableImage {
|
||||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<'a, I>(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError>
|
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
ImmutableImage::with_mipmaps(
|
ImmutableImage::with_mipmaps(
|
||||||
device,
|
device,
|
||||||
dimensions,
|
dimensions,
|
||||||
format,
|
format,
|
||||||
MipmapsCount::One,
|
MipmapsCount::One,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
#[deprecated(note = "use ImmutableImage::uninitialized instead")]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn with_mipmaps<'a, I, M>(
|
pub fn with_mipmaps(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
mip_levels: M,
|
mip_levels: impl Into<MipmapsCount>,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError>
|
) -> Result<Arc<ImmutableImage>, ImmutableImageCreationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
M: Into<MipmapsCount>,
|
|
||||||
{
|
|
||||||
let usage = ImageUsage {
|
let usage = ImageUsage {
|
||||||
transfer_src: true, // for blits
|
transfer_src: true, // for blits
|
||||||
transfer_dst: true,
|
transfer_dst: true,
|
||||||
@ -150,7 +143,7 @@ impl ImmutableImage {
|
|||||||
usage,
|
usage,
|
||||||
flags,
|
flags,
|
||||||
ImageLayout::ShaderReadOnlyOptimal,
|
ImageLayout::ShaderReadOnlyOptimal,
|
||||||
queue_families,
|
queue_family_indices,
|
||||||
)?;
|
)?;
|
||||||
Ok(image)
|
Ok(image)
|
||||||
}
|
}
|
||||||
@ -158,24 +151,18 @@ impl ImmutableImage {
|
|||||||
/// Builds an uninitialized immutable image.
|
/// Builds an uninitialized immutable image.
|
||||||
///
|
///
|
||||||
/// Returns two things: the image, and a special access that should be used for the initial upload to the image.
|
/// Returns two things: the image, and a special access that should be used for the initial upload to the image.
|
||||||
pub fn uninitialized<'a, I, M>(
|
pub fn uninitialized(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
mip_levels: M,
|
mip_levels: impl Into<MipmapsCount>,
|
||||||
usage: ImageUsage,
|
usage: ImageUsage,
|
||||||
flags: ImageCreateFlags,
|
flags: ImageCreateFlags,
|
||||||
layout: ImageLayout,
|
layout: ImageLayout,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<(Arc<ImmutableImage>, Arc<ImmutableImageInitialization>), ImmutableImageCreationError>
|
) -> Result<(Arc<ImmutableImage>, Arc<ImmutableImageInitialization>), ImmutableImageCreationError>
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
M: Into<MipmapsCount>,
|
|
||||||
{
|
{
|
||||||
let queue_families = queue_families
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let image = UnsafeImage::new(
|
let image = UnsafeImage::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
@ -188,8 +175,8 @@ impl ImmutableImage {
|
|||||||
MipmapsCount::One => 1,
|
MipmapsCount::One => 1,
|
||||||
},
|
},
|
||||||
usage,
|
usage,
|
||||||
sharing: if queue_families.len() >= 2 {
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
Sharing::Concurrent(queue_family_indices)
|
||||||
} else {
|
} else {
|
||||||
Sharing::Exclusive
|
Sharing::Exclusive
|
||||||
},
|
},
|
||||||
@ -209,7 +196,7 @@ impl ImmutableImage {
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
Some(DedicatedAllocation::Image(&image)),
|
Some(DedicatedAllocation::Image(&image)),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -299,12 +286,16 @@ impl ImmutableImage {
|
|||||||
usage,
|
usage,
|
||||||
flags,
|
flags,
|
||||||
layout,
|
layout,
|
||||||
source.device().active_queue_families(),
|
source
|
||||||
|
.device()
|
||||||
|
.active_queue_family_indices()
|
||||||
|
.iter()
|
||||||
|
.copied(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
source.device().clone(),
|
source.device().clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::MultipleSubmit,
|
CommandBufferUsage::MultipleSubmit,
|
||||||
)?;
|
)?;
|
||||||
cbb.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(source, initializer))
|
cbb.copy_buffer_to_image(CopyBufferToImageInfo::buffer_image(source, initializer))
|
||||||
|
@ -12,7 +12,7 @@ use super::{
|
|||||||
ImageDescriptorLayouts, ImageDimensions, ImageInner, ImageLayout, ImageUsage,
|
ImageDescriptorLayouts, ImageDimensions, ImageInner, ImageLayout, ImageUsage,
|
||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{physical::QueueFamily, Device, DeviceOwned, Queue},
|
device::{Device, DeviceOwned, Queue},
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{sys::UnsafeImageCreateInfo, view::ImageView},
|
image::{sys::UnsafeImageCreateInfo, view::ImageView},
|
||||||
memory::{
|
memory::{
|
||||||
@ -53,15 +53,12 @@ where
|
|||||||
impl StorageImage {
|
impl StorageImage {
|
||||||
/// Creates a new image with the given dimensions and format.
|
/// Creates a new image with the given dimensions and format.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new<'a, I>(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||||
where
|
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
let aspects = format.aspects();
|
let aspects = format.aspects();
|
||||||
let is_depth = aspects.depth || aspects.stencil;
|
let is_depth = aspects.depth || aspects.stencil;
|
||||||
|
|
||||||
@ -81,25 +78,26 @@ impl StorageImage {
|
|||||||
};
|
};
|
||||||
let flags = ImageCreateFlags::empty();
|
let flags = ImageCreateFlags::empty();
|
||||||
|
|
||||||
StorageImage::with_usage(device, dimensions, format, usage, flags, queue_families)
|
StorageImage::with_usage(
|
||||||
|
device,
|
||||||
|
dimensions,
|
||||||
|
format,
|
||||||
|
usage,
|
||||||
|
flags,
|
||||||
|
queue_family_indices,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `new`, but allows specifying the usage.
|
/// Same as `new`, but allows specifying the usage.
|
||||||
pub fn with_usage<'a, I>(
|
pub fn with_usage(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
usage: ImageUsage,
|
usage: ImageUsage,
|
||||||
flags: ImageCreateFlags,
|
flags: ImageCreateFlags,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||||
where
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
let queue_families = queue_families
|
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let image = UnsafeImage::new(
|
let image = UnsafeImage::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
@ -107,8 +105,8 @@ impl StorageImage {
|
|||||||
dimensions,
|
dimensions,
|
||||||
format: Some(format),
|
format: Some(format),
|
||||||
usage,
|
usage,
|
||||||
sharing: if queue_families.len() >= 2 {
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
Sharing::Concurrent(queue_family_indices)
|
||||||
} else {
|
} else {
|
||||||
Sharing::Exclusive
|
Sharing::Exclusive
|
||||||
},
|
},
|
||||||
@ -128,7 +126,7 @@ impl StorageImage {
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
Some(DedicatedAllocation::Image(&image)),
|
Some(DedicatedAllocation::Image(&image)),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -147,21 +145,15 @@ impl StorageImage {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_exportable_fd<'a, I>(
|
pub fn new_with_exportable_fd(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
dimensions: ImageDimensions,
|
dimensions: ImageDimensions,
|
||||||
format: Format,
|
format: Format,
|
||||||
usage: ImageUsage,
|
usage: ImageUsage,
|
||||||
flags: ImageCreateFlags,
|
flags: ImageCreateFlags,
|
||||||
queue_families: I,
|
queue_family_indices: impl IntoIterator<Item = u32>,
|
||||||
) -> Result<Arc<StorageImage>, ImageCreationError>
|
) -> Result<Arc<StorageImage>, ImageCreationError> {
|
||||||
where
|
let queue_family_indices: SmallVec<[_; 4]> = queue_family_indices.into_iter().collect();
|
||||||
I: IntoIterator<Item = QueueFamily<'a>>,
|
|
||||||
{
|
|
||||||
let queue_families = queue_families
|
|
||||||
.into_iter()
|
|
||||||
.map(|f| f.id())
|
|
||||||
.collect::<SmallVec<[u32; 4]>>();
|
|
||||||
|
|
||||||
let image = UnsafeImage::new(
|
let image = UnsafeImage::new(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
@ -169,8 +161,8 @@ impl StorageImage {
|
|||||||
dimensions,
|
dimensions,
|
||||||
format: Some(format),
|
format: Some(format),
|
||||||
usage,
|
usage,
|
||||||
sharing: if queue_families.len() >= 2 {
|
sharing: if queue_family_indices.len() >= 2 {
|
||||||
Sharing::Concurrent(queue_families.iter().cloned().collect())
|
Sharing::Concurrent(queue_family_indices)
|
||||||
} else {
|
} else {
|
||||||
Sharing::Exclusive
|
Sharing::Exclusive
|
||||||
},
|
},
|
||||||
@ -194,7 +186,7 @@ impl StorageImage {
|
|||||||
MappingRequirement::DoNotMap,
|
MappingRequirement::DoNotMap,
|
||||||
DedicatedAllocation::Image(&image),
|
DedicatedAllocation::Image(&image),
|
||||||
|t| {
|
|t| {
|
||||||
if t.is_device_local() {
|
if t.property_flags.device_local {
|
||||||
AllocFromRequirementsFilter::Preferred
|
AllocFromRequirementsFilter::Preferred
|
||||||
} else {
|
} else {
|
||||||
AllocFromRequirementsFilter::Allowed
|
AllocFromRequirementsFilter::Allowed
|
||||||
@ -232,7 +224,7 @@ impl StorageImage {
|
|||||||
format,
|
format,
|
||||||
usage,
|
usage,
|
||||||
flags,
|
flags,
|
||||||
Some(queue.family()),
|
Some(queue.queue_family_index()),
|
||||||
);
|
);
|
||||||
match image_result {
|
match image_result {
|
||||||
Ok(image) => {
|
Ok(image) => {
|
||||||
@ -359,7 +351,7 @@ mod tests {
|
|||||||
array_layers: 1,
|
array_layers: 1,
|
||||||
},
|
},
|
||||||
Format::R8G8B8A8_UNORM,
|
Format::R8G8B8A8_UNORM,
|
||||||
Some(queue.family()),
|
Some(queue.queue_family_index()),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -485,16 +485,24 @@ impl UnsafeImage {
|
|||||||
|
|
||||||
match sharing {
|
match sharing {
|
||||||
Sharing::Exclusive => (),
|
Sharing::Exclusive => (),
|
||||||
Sharing::Concurrent(ids) => {
|
Sharing::Concurrent(queue_family_indices) => {
|
||||||
// VUID-VkImageCreateInfo-sharingMode-00942
|
// VUID-VkImageCreateInfo-sharingMode-00942
|
||||||
ids.sort_unstable();
|
queue_family_indices.sort_unstable();
|
||||||
ids.dedup();
|
queue_family_indices.dedup();
|
||||||
assert!(ids.len() >= 2);
|
assert!(queue_family_indices.len() >= 2);
|
||||||
|
|
||||||
for &id in ids.iter() {
|
for &queue_family_index in queue_family_indices.iter() {
|
||||||
// VUID-VkImageCreateInfo-sharingMode-01420
|
// VUID-VkImageCreateInfo-sharingMode-01420
|
||||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
if queue_family_index
|
||||||
return Err(ImageCreationError::SharingInvalidQueueFamilyId { id });
|
>= device.physical_device().queue_family_properties().len() as u32
|
||||||
|
{
|
||||||
|
return Err(ImageCreationError::SharingQueueFamilyIndexOutOfRange {
|
||||||
|
queue_family_index,
|
||||||
|
queue_family_count: device
|
||||||
|
.physical_device()
|
||||||
|
.queue_family_properties()
|
||||||
|
.len() as u32,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1022,7 +1030,7 @@ impl UnsafeImage {
|
|||||||
let mem_reqs = mem_reqs.assume_init();
|
let mem_reqs = mem_reqs.assume_init();
|
||||||
mem_reqs.size <= memory.allocation_size() - offset
|
mem_reqs.size <= memory.allocation_size() - offset
|
||||||
&& offset % mem_reqs.alignment == 0
|
&& offset % mem_reqs.alignment == 0
|
||||||
&& mem_reqs.memory_type_bits & (1 << memory.memory_type().id()) != 0
|
&& mem_reqs.memory_type_bits & (1 << memory.memory_type_index()) != 0
|
||||||
});
|
});
|
||||||
|
|
||||||
(fns.v1_0.bind_image_memory)(
|
(fns.v1_0.bind_image_memory)(
|
||||||
@ -1626,10 +1634,11 @@ pub enum ImageCreationError {
|
|||||||
supported: SampleCounts,
|
supported: SampleCounts,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The sharing mode was set to `Concurrent`, but one of the specified queue family ids was not
|
/// The sharing mode was set to `Concurrent`, but one of the specified queue family indices was
|
||||||
/// valid.
|
/// out of range.
|
||||||
SharingInvalidQueueFamilyId {
|
SharingQueueFamilyIndexOutOfRange {
|
||||||
id: u32,
|
queue_family_index: u32,
|
||||||
|
queue_family_count: u32,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A YCbCr format was given, but the specified width and/or height was not a multiple of 2
|
/// A YCbCr format was given, but the specified width and/or height was not a multiple of 2
|
||||||
@ -1757,8 +1766,8 @@ impl Display for ImageCreationError {
|
|||||||
"the sample count is not supported by the device for this image configuration"
|
"the sample count is not supported by the device for this image configuration"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Self::SharingInvalidQueueFamilyId { .. } => {
|
Self::SharingQueueFamilyIndexOutOfRange { .. } => {
|
||||||
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family ids was not valid")
|
write!(f, "the sharing mode was set to `Concurrent`, but one of the specified queue family indices was out of range")
|
||||||
}
|
}
|
||||||
Self::YcbcrFormatInvalidDimensions => {
|
Self::YcbcrFormatInvalidDimensions => {
|
||||||
write!(f, "a YCbCr format was given, but the specified width and/or height was not a multiple of 2 as required by the format's chroma subsampling")
|
write!(f, "a YCbCr format was given, but the specified width and/or height was not a multiple of 2 as required by the format's chroma subsampling")
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
//!
|
//!
|
||||||
//! # let library = VulkanLibrary::new().unwrap();
|
//! # let library = VulkanLibrary::new().unwrap();
|
||||||
//! # let instance = Instance::new(library, Default::default()).unwrap();
|
//! # let instance = Instance::new(library, Default::default()).unwrap();
|
||||||
//! for physical_device in PhysicalDevice::enumerate(&instance) {
|
//! for physical_device in instance.enumerate_physical_devices().unwrap() {
|
||||||
//! println!("Available device: {}", physical_device.properties().device_name);
|
//! println!("Available device: {}", physical_device.properties().device_name);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
@ -45,7 +45,7 @@
|
|||||||
//! # Enumerating physical devices and creating a device
|
//! # Enumerating physical devices and creating a device
|
||||||
//!
|
//!
|
||||||
//! After you have created an instance, the next step is usually to enumerate the physical devices
|
//! After you have created an instance, the next step is usually to enumerate the physical devices
|
||||||
//! that are available on the system with `PhysicalDevice::enumerate()` (see above).
|
//! that are available on the system with `Instance::enumerate_physical_devices()` (see above).
|
||||||
//!
|
//!
|
||||||
//! When choosing which physical device to use, keep in mind that physical devices may or may not
|
//! When choosing which physical device to use, keep in mind that physical devices may or may not
|
||||||
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
|
//! be able to draw to a certain surface (ie. to a window or a monitor), or may even not be able
|
||||||
@ -57,9 +57,8 @@
|
|||||||
use self::debug::{DebugUtilsMessengerCreateInfo, UserCallback};
|
use self::debug::{DebugUtilsMessengerCreateInfo, UserCallback};
|
||||||
pub use self::{extensions::InstanceExtensions, layers::LayerProperties};
|
pub use self::{extensions::InstanceExtensions, layers::LayerProperties};
|
||||||
use crate::{
|
use crate::{
|
||||||
device::physical::{init_physical_devices, PhysicalDeviceInfo},
|
device::physical::PhysicalDevice, instance::debug::trampoline, OomError, RequiresOneOf,
|
||||||
instance::debug::trampoline,
|
VulkanError, VulkanLibrary, VulkanObject,
|
||||||
OomError, RequiresOneOf, VulkanError, VulkanLibrary, VulkanObject,
|
|
||||||
};
|
};
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
extensions::{ExtensionRestriction, ExtensionRestrictionError},
|
extensions::{ExtensionRestriction, ExtensionRestrictionError},
|
||||||
@ -234,7 +233,6 @@ mod layers;
|
|||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
handle: ash::vk::Instance,
|
handle: ash::vk::Instance,
|
||||||
fns: InstanceFunctions,
|
fns: InstanceFunctions,
|
||||||
pub(crate) physical_device_infos: Vec<PhysicalDeviceInfo>,
|
|
||||||
|
|
||||||
api_version: Version,
|
api_version: Version,
|
||||||
enabled_extensions: InstanceExtensions,
|
enabled_extensions: InstanceExtensions,
|
||||||
@ -452,10 +450,9 @@ impl Instance {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut instance = Instance {
|
Ok(Arc::new(Instance {
|
||||||
handle,
|
handle,
|
||||||
fns,
|
fns,
|
||||||
physical_device_infos: Vec::new(),
|
|
||||||
|
|
||||||
api_version,
|
api_version,
|
||||||
enabled_extensions,
|
enabled_extensions,
|
||||||
@ -463,12 +460,7 @@ impl Instance {
|
|||||||
library,
|
library,
|
||||||
max_api_version,
|
max_api_version,
|
||||||
_user_callbacks: user_callbacks,
|
_user_callbacks: user_callbacks,
|
||||||
};
|
}))
|
||||||
|
|
||||||
// Enumerating all physical devices.
|
|
||||||
instance.physical_device_infos = init_physical_devices(&instance)?;
|
|
||||||
|
|
||||||
Ok(Arc::new(instance))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the Vulkan library used to create this instance.
|
/// Returns the Vulkan library used to create this instance.
|
||||||
@ -510,6 +502,60 @@ impl Instance {
|
|||||||
pub fn enabled_layers(&self) -> &[String] {
|
pub fn enabled_layers(&self) -> &[String] {
|
||||||
&self.enabled_layers
|
&self.enabled_layers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator that enumerates the physical devices available.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// # use vulkano::{
|
||||||
|
/// # instance::{Instance, InstanceExtensions},
|
||||||
|
/// # Version, VulkanLibrary,
|
||||||
|
/// # };
|
||||||
|
///
|
||||||
|
/// # let library = VulkanLibrary::new().unwrap();
|
||||||
|
/// # let instance = Instance::new(library, Default::default()).unwrap();
|
||||||
|
/// for physical_device in instance.enumerate_physical_devices().unwrap() {
|
||||||
|
/// println!("Available device: {}", physical_device.properties().device_name);
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
pub fn enumerate_physical_devices(
|
||||||
|
self: &Arc<Self>,
|
||||||
|
) -> Result<impl ExactSizeIterator<Item = Arc<PhysicalDevice>>, VulkanError> {
|
||||||
|
let fns = self.fns();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
let handles = loop {
|
||||||
|
let mut count = 0;
|
||||||
|
(fns.v1_0.enumerate_physical_devices)(self.handle, &mut count, ptr::null_mut())
|
||||||
|
.result()
|
||||||
|
.map_err(VulkanError::from)?;
|
||||||
|
|
||||||
|
let mut handles = Vec::with_capacity(count as usize);
|
||||||
|
let result = (fns.v1_0.enumerate_physical_devices)(
|
||||||
|
self.handle,
|
||||||
|
&mut count,
|
||||||
|
handles.as_mut_ptr(),
|
||||||
|
);
|
||||||
|
|
||||||
|
match result {
|
||||||
|
ash::vk::Result::SUCCESS => {
|
||||||
|
handles.set_len(count as usize);
|
||||||
|
break handles;
|
||||||
|
}
|
||||||
|
ash::vk::Result::INCOMPLETE => (),
|
||||||
|
err => return Err(VulkanError::from(err)),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let physical_devices: SmallVec<[_; 4]> = handles
|
||||||
|
.into_iter()
|
||||||
|
.map(|handle| PhysicalDevice::from_handle(handle, self.clone()))
|
||||||
|
.collect::<Result<_, _>>()?;
|
||||||
|
|
||||||
|
Ok(physical_devices.into_iter())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Instance {
|
impl Drop for Instance {
|
||||||
@ -553,7 +599,6 @@ impl Debug for Instance {
|
|||||||
let Self {
|
let Self {
|
||||||
handle,
|
handle,
|
||||||
fns,
|
fns,
|
||||||
physical_device_infos,
|
|
||||||
api_version,
|
api_version,
|
||||||
enabled_extensions,
|
enabled_extensions,
|
||||||
enabled_layers,
|
enabled_layers,
|
||||||
@ -565,7 +610,6 @@ impl Debug for Instance {
|
|||||||
f.debug_struct("Instance")
|
f.debug_struct("Instance")
|
||||||
.field("handle", handle)
|
.field("handle", handle)
|
||||||
.field("fns", fns)
|
.field("fns", fns)
|
||||||
.field("physical_device_infos", physical_device_infos)
|
|
||||||
.field("api_version", api_version)
|
.field("api_version", api_version)
|
||||||
.field("enabled_extensions", enabled_extensions)
|
.field("enabled_extensions", enabled_extensions)
|
||||||
.field("enabled_layers", enabled_layers)
|
.field("enabled_layers", enabled_layers)
|
||||||
@ -763,28 +807,9 @@ impl From<VulkanError> for InstanceCreationError {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::device::physical::PhysicalDevice;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_instance() {
|
fn create_instance() {
|
||||||
let _ = 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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
//! - The [`PhysicalDevice`](crate::device::physical::PhysicalDevice) object represents a
|
//! - The [`PhysicalDevice`](crate::device::physical::PhysicalDevice) object represents a
|
||||||
//! Vulkan-capable device that is available on the system (eg. a graphics card, a software
|
//! Vulkan-capable device that is available on the system (eg. a graphics card, a software
|
||||||
//! implementation, etc.). Physical devices can be enumerated from an instance with
|
//! implementation, etc.). Physical devices can be enumerated from an instance with
|
||||||
//! [`PhysicalDevice::enumerate`](crate::device::physical::PhysicalDevice::enumerate).
|
//! [`Instance::enumerate_physical_devices`](crate::instance::Instance::enumerate_physical_devices).
|
||||||
//!
|
//!
|
||||||
//! - Once you have chosen a physical device to use, you can create a
|
//! - Once you have chosen a physical device to use, you can create a
|
||||||
//! [`Device`](crate::device::Device) object from it. The `Device` is the most important
|
//! [`Device`](crate::device::Device) object from it. The `Device` is the most important
|
||||||
|
@ -142,11 +142,14 @@ impl VulkanLibrary {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceExtensions::from(
|
extension_properties
|
||||||
extension_properties
|
.iter()
|
||||||
.iter()
|
.map(|property| {
|
||||||
.map(|property| CStr::from_ptr(property.extension_name.as_ptr())),
|
CStr::from_ptr(property.extension_name.as_ptr())
|
||||||
)
|
.to_str()
|
||||||
|
.unwrap()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Arc::new(VulkanLibrary {
|
Ok(Arc::new(VulkanLibrary {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
macro_rules! vulkan_bitflags {
|
macro_rules! vulkan_bitflags {
|
||||||
{
|
{
|
||||||
$(#[doc = $ty_doc:literal])*
|
$(#[doc = $ty_doc:literal])*
|
||||||
$ty:ident = $ty_ffi:ident($repr:ty);
|
$ty:ident = $ty_ffi:ident($repr:ty);
|
||||||
|
|
||||||
$(
|
$(
|
||||||
@ -17,7 +17,7 @@ macro_rules! vulkan_bitflags {
|
|||||||
$flag_name:ident = $flag_name_ffi:ident,
|
$flag_name:ident = $flag_name_ffi:ident,
|
||||||
)+
|
)+
|
||||||
} => {
|
} => {
|
||||||
$(#[doc = $ty_doc])*
|
$(#[doc = $ty_doc])*
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct $ty {
|
pub struct $ty {
|
||||||
$(
|
$(
|
||||||
@ -131,27 +131,27 @@ macro_rules! vulkan_bitflags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$ty> for ash::vk::$ty_ffi {
|
impl From<$ty> for ash::vk::$ty_ffi {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: $ty) -> Self {
|
fn from(val: $ty) -> Self {
|
||||||
let mut result = ash::vk::$ty_ffi::empty();
|
let mut result = ash::vk::$ty_ffi::empty();
|
||||||
$(
|
$(
|
||||||
if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi }
|
if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi }
|
||||||
)+
|
)+
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ash::vk::$ty_ffi> for $ty {
|
impl From<ash::vk::$ty_ffi> for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: ash::vk::$ty_ffi) -> Self {
|
fn from(val: ash::vk::$ty_ffi) -> Self {
|
||||||
Self {
|
Self {
|
||||||
$(
|
$(
|
||||||
$flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi),
|
$flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi),
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for $ty {
|
impl Default for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -239,7 +239,7 @@ macro_rules! vulkan_bitflags {
|
|||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
$(#[doc = $ty_doc:literal])*
|
$(#[doc = $ty_doc:literal])*
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
$ty:ident = $ty_ffi:ident($repr:ty);
|
$ty:ident = $ty_ffi:ident($repr:ty);
|
||||||
|
|
||||||
@ -254,7 +254,7 @@ macro_rules! vulkan_bitflags {
|
|||||||
,
|
,
|
||||||
)+
|
)+
|
||||||
} => {
|
} => {
|
||||||
$(#[doc = $ty_doc])*
|
$(#[doc = $ty_doc])*
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct $ty {
|
pub struct $ty {
|
||||||
$(
|
$(
|
||||||
@ -452,28 +452,28 @@ macro_rules! vulkan_bitflags {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$ty> for ash::vk::$ty_ffi {
|
impl From<$ty> for ash::vk::$ty_ffi {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: $ty) -> Self {
|
fn from(val: $ty) -> Self {
|
||||||
let mut result = ash::vk::$ty_ffi::empty();
|
let mut result = ash::vk::$ty_ffi::empty();
|
||||||
$(
|
$(
|
||||||
if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi }
|
if val.$flag_name { result |= ash::vk::$ty_ffi::$flag_name_ffi }
|
||||||
)+
|
)+
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ash::vk::$ty_ffi> for $ty {
|
impl From<ash::vk::$ty_ffi> for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: ash::vk::$ty_ffi) -> Self {
|
fn from(val: ash::vk::$ty_ffi) -> Self {
|
||||||
Self {
|
Self {
|
||||||
$(
|
$(
|
||||||
$flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi),
|
$flag_name: val.intersects(ash::vk::$ty_ffi::$flag_name_ffi),
|
||||||
)+
|
)+
|
||||||
_ne: crate::NonExhaustive(()),
|
_ne: crate::NonExhaustive(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for $ty {
|
impl Default for $ty {
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -555,7 +555,7 @@ macro_rules! vulkan_bitflags {
|
|||||||
|
|
||||||
macro_rules! vulkan_enum {
|
macro_rules! vulkan_enum {
|
||||||
{
|
{
|
||||||
$(#[doc = $ty_doc:literal])*
|
$(#[doc = $ty_doc:literal])*
|
||||||
$ty:ident = $ty_ffi:ident($repr:ty);
|
$ty:ident = $ty_ffi:ident($repr:ty);
|
||||||
|
|
||||||
$(
|
$(
|
||||||
@ -563,7 +563,7 @@ macro_rules! vulkan_enum {
|
|||||||
$flag_name:ident = $flag_name_ffi:ident,
|
$flag_name:ident = $flag_name_ffi:ident,
|
||||||
)+
|
)+
|
||||||
} => {
|
} => {
|
||||||
$(#[doc = $ty_doc])*
|
$(#[doc = $ty_doc])*
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
#[repr($repr)]
|
#[repr($repr)]
|
||||||
pub enum $ty {
|
pub enum $ty {
|
||||||
@ -573,30 +573,30 @@ macro_rules! vulkan_enum {
|
|||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<$ty> for ash::vk::$ty_ffi {
|
impl From<$ty> for ash::vk::$ty_ffi {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: $ty) -> Self {
|
fn from(val: $ty) -> Self {
|
||||||
ash::vk::$ty_ffi::from_raw(val as $repr)
|
ash::vk::$ty_ffi::from_raw(val as $repr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<ash::vk::$ty_ffi> for $ty {
|
impl TryFrom<ash::vk::$ty_ffi> for $ty {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(val: ash::vk::$ty_ffi) -> Result<Self, Self::Error> {
|
fn try_from(val: ash::vk::$ty_ffi) -> Result<Self, Self::Error> {
|
||||||
Ok(match val {
|
Ok(match val {
|
||||||
$(
|
$(
|
||||||
ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name,
|
ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name,
|
||||||
)+
|
)+
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
$(#[doc = $ty_doc:literal])*
|
$(#[doc = $ty_doc:literal])*
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
$ty:ident = $ty_ffi:ident($repr:ty);
|
$ty:ident = $ty_ffi:ident($repr:ty);
|
||||||
|
|
||||||
@ -611,7 +611,7 @@ macro_rules! vulkan_enum {
|
|||||||
,
|
,
|
||||||
)+
|
)+
|
||||||
} => {
|
} => {
|
||||||
$(#[doc = $ty_doc])*
|
$(#[doc = $ty_doc])*
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
#[non_exhaustive]
|
#[non_exhaustive]
|
||||||
#[repr($repr)]
|
#[repr($repr)]
|
||||||
@ -733,30 +733,30 @@ macro_rules! vulkan_enum {
|
|||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<$ty> for ash::vk::$ty_ffi {
|
impl From<$ty> for ash::vk::$ty_ffi {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(val: $ty) -> Self {
|
fn from(val: $ty) -> Self {
|
||||||
ash::vk::$ty_ffi::from_raw(val as $repr)
|
ash::vk::$ty_ffi::from_raw(val as $repr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<ash::vk::$ty_ffi> for $ty {
|
impl TryFrom<ash::vk::$ty_ffi> for $ty {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn try_from(val: ash::vk::$ty_ffi) -> Result<Self, Self::Error> {
|
fn try_from(val: ash::vk::$ty_ffi) -> Result<Self, Self::Error> {
|
||||||
Ok(match val {
|
Ok(match val {
|
||||||
$(
|
$(
|
||||||
ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name,
|
ash::vk::$ty_ffi::$flag_name_ffi => Self::$flag_name,
|
||||||
)+
|
)+
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
use super::DedicatedAllocation;
|
use super::DedicatedAllocation;
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{physical::MemoryType, Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
macros::{vulkan_bitflags, vulkan_enum},
|
macros::{vulkan_bitflags, vulkan_enum},
|
||||||
DeviceSize, OomError, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject,
|
DeviceSize, OomError, RequirementNotMet, RequiresOneOf, Version, VulkanError, VulkanObject,
|
||||||
};
|
};
|
||||||
@ -35,14 +35,14 @@ use std::{
|
|||||||
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
|
/// use vulkano::memory::{DeviceMemory, MemoryAllocateInfo};
|
||||||
///
|
///
|
||||||
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||||
/// let memory_type = device.physical_device().memory_types().next().unwrap();
|
/// let memory_type_index = 0;
|
||||||
///
|
///
|
||||||
/// // Allocates 1KB of memory.
|
/// // Allocates 1KB of memory.
|
||||||
/// let memory = DeviceMemory::allocate(
|
/// let memory = DeviceMemory::allocate(
|
||||||
/// device.clone(),
|
/// device.clone(),
|
||||||
/// MemoryAllocateInfo {
|
/// MemoryAllocateInfo {
|
||||||
/// allocation_size: 1024,
|
/// allocation_size: 1024,
|
||||||
/// memory_type_index: memory_type.id(),
|
/// memory_type_index,
|
||||||
/// ..Default::default()
|
/// ..Default::default()
|
||||||
/// },
|
/// },
|
||||||
/// ).unwrap();
|
/// ).unwrap();
|
||||||
@ -150,19 +150,21 @@ impl DeviceMemory {
|
|||||||
*dedicated_allocation = None;
|
*dedicated_allocation = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let memory_properties = device.physical_device().memory_properties();
|
||||||
|
|
||||||
// VUID-vkAllocateMemory-pAllocateInfo-01714
|
// VUID-vkAllocateMemory-pAllocateInfo-01714
|
||||||
let memory_type = device
|
let memory_type = memory_properties
|
||||||
.physical_device()
|
.memory_types
|
||||||
.memory_type_by_id(memory_type_index)
|
.get(memory_type_index as usize)
|
||||||
.ok_or_else(|| DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
.ok_or(DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
||||||
memory_type_index,
|
memory_type_index,
|
||||||
memory_type_count: device.physical_device().memory_types().len() as u32,
|
memory_type_count: memory_properties.memory_types.len() as u32,
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872
|
// VUID-VkMemoryAllocateInfo-memoryTypeIndex-01872
|
||||||
if memory_type.is_protected() && !device.enabled_features().protected_memory {
|
if memory_type.property_flags.protected && !device.enabled_features().protected_memory {
|
||||||
return Err(DeviceMemoryAllocationError::RequirementNotMet {
|
return Err(DeviceMemoryAllocationError::RequirementNotMet {
|
||||||
required_for: "`allocate_info.memory_type_index` refers to a memory type where `flags.protected` is set",
|
required_for: "`allocate_info.memory_type_index` refers to a memory type where `property_flags.protected` is set",
|
||||||
requires_one_of: RequiresOneOf {
|
requires_one_of: RequiresOneOf {
|
||||||
features: &["protected_memory"],
|
features: &["protected_memory"],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -174,7 +176,7 @@ impl DeviceMemory {
|
|||||||
assert!(allocation_size != 0);
|
assert!(allocation_size != 0);
|
||||||
|
|
||||||
// VUID-vkAllocateMemory-pAllocateInfo-01713
|
// VUID-vkAllocateMemory-pAllocateInfo-01713
|
||||||
let heap_size = memory_type.heap().size();
|
let heap_size = memory_properties.memory_heaps[memory_type.heap_index as usize].size;
|
||||||
if heap_size != 0 && allocation_size > heap_size {
|
if heap_size != 0 && allocation_size > heap_size {
|
||||||
return Err(DeviceMemoryAllocationError::MemoryTypeHeapSizeExceeded {
|
return Err(DeviceMemoryAllocationError::MemoryTypeHeapSizeExceeded {
|
||||||
allocation_size,
|
allocation_size,
|
||||||
@ -473,13 +475,10 @@ impl DeviceMemory {
|
|||||||
Ok(handle)
|
Ok(handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the memory type that this memory was allocated from.
|
/// Returns the index of the memory type that this memory was allocated from.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn memory_type(&self) -> MemoryType {
|
pub fn memory_type_index(&self) -> u32 {
|
||||||
self.device
|
self.memory_type_index
|
||||||
.physical_device()
|
|
||||||
.memory_type_by_id(self.memory_type_index)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the size in bytes of the memory allocation.
|
/// Returns the size in bytes of the memory allocation.
|
||||||
@ -1122,16 +1121,21 @@ impl From<RequirementNotMet> for DeviceMemoryExportError {
|
|||||||
///
|
///
|
||||||
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
/// # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||||
/// // The memory type must be mappable.
|
/// // The memory type must be mappable.
|
||||||
/// let memory_type = device.physical_device().memory_types()
|
/// let memory_type_index = device
|
||||||
/// .filter(|t| t.is_host_visible())
|
/// .physical_device()
|
||||||
/// .next().unwrap(); // Vk specs guarantee that this can't fail
|
/// .memory_properties()
|
||||||
|
/// .memory_types
|
||||||
|
/// .iter()
|
||||||
|
/// .position(|t| t.property_flags.host_visible)
|
||||||
|
/// .map(|i| i as u32)
|
||||||
|
/// .unwrap(); // Vk specs guarantee that this can't fail
|
||||||
///
|
///
|
||||||
/// // Allocates 1KB of memory.
|
/// // Allocates 1KB of memory.
|
||||||
/// let memory = DeviceMemory::allocate(
|
/// let memory = DeviceMemory::allocate(
|
||||||
/// device.clone(),
|
/// device.clone(),
|
||||||
/// MemoryAllocateInfo {
|
/// MemoryAllocateInfo {
|
||||||
/// allocation_size: 1024,
|
/// allocation_size: 1024,
|
||||||
/// memory_type_index: memory_type.id(),
|
/// memory_type_index,
|
||||||
/// ..Default::default()
|
/// ..Default::default()
|
||||||
/// },
|
/// },
|
||||||
/// ).unwrap();
|
/// ).unwrap();
|
||||||
@ -1191,13 +1195,16 @@ impl MappedDeviceMemory {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let device = memory.device();
|
||||||
|
let memory_type = &device.physical_device().memory_properties().memory_types
|
||||||
|
[memory.memory_type_index() as usize];
|
||||||
|
|
||||||
// VUID-vkMapMemory-memory-00682
|
// VUID-vkMapMemory-memory-00682
|
||||||
if !memory.memory_type().is_host_visible() {
|
if !memory_type.property_flags.host_visible {
|
||||||
return Err(MemoryMapError::NotHostVisible);
|
return Err(MemoryMapError::NotHostVisible);
|
||||||
}
|
}
|
||||||
|
|
||||||
let device = memory.device();
|
let coherent = memory_type.property_flags.host_coherent;
|
||||||
let coherent = memory.memory_type().is_host_coherent();
|
|
||||||
let atom_size = device.physical_device().properties().non_coherent_atom_size;
|
let atom_size = device.physical_device().properties().non_coherent_atom_size;
|
||||||
|
|
||||||
// Not required for merely mapping, but without this check the user can end up with
|
// Not required for merely mapping, but without this check the user can end up with
|
||||||
@ -1544,12 +1551,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create() {
|
fn create() {
|
||||||
let (device, _) = gfx_dev_and_queue!();
|
let (device, _) = gfx_dev_and_queue!();
|
||||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
|
||||||
let _ = DeviceMemory::allocate(
|
let _ = DeviceMemory::allocate(
|
||||||
device.clone(),
|
device,
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: 256,
|
allocation_size: 256,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index: 0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -1559,13 +1565,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn zero_size() {
|
fn zero_size() {
|
||||||
let (device, _) = gfx_dev_and_queue!();
|
let (device, _) = gfx_dev_and_queue!();
|
||||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
|
||||||
assert_should_panic!({
|
assert_should_panic!({
|
||||||
let _ = DeviceMemory::allocate(
|
let _ = DeviceMemory::allocate(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: 0,
|
allocation_size: 0,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index: 0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -1577,17 +1582,20 @@ mod tests {
|
|||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
fn oom_single() {
|
fn oom_single() {
|
||||||
let (device, _) = gfx_dev_and_queue!();
|
let (device, _) = gfx_dev_and_queue!();
|
||||||
let memory_type = device
|
let memory_type_index = device
|
||||||
.physical_device()
|
.physical_device()
|
||||||
.memory_types()
|
.memory_properties()
|
||||||
.find(|m| !m.is_lazily_allocated())
|
.memory_types
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find_map(|(i, m)| (!m.property_flags.lazily_allocated).then_some(i as u32))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match DeviceMemory::allocate(
|
match DeviceMemory::allocate(
|
||||||
device.clone(),
|
device,
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: 0xffffffffffffffff,
|
allocation_size: 0xffffffffffffffff,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@ -1600,12 +1608,17 @@ mod tests {
|
|||||||
#[ignore] // TODO: test fails for now on Mesa+Intel
|
#[ignore] // TODO: test fails for now on Mesa+Intel
|
||||||
fn oom_multi() {
|
fn oom_multi() {
|
||||||
let (device, _) = gfx_dev_and_queue!();
|
let (device, _) = gfx_dev_and_queue!();
|
||||||
let memory_type = device
|
let (memory_type_index, memory_type) = device
|
||||||
.physical_device()
|
.physical_device()
|
||||||
.memory_types()
|
.memory_properties()
|
||||||
.find(|m| !m.is_lazily_allocated())
|
.memory_types
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.find_map(|(i, m)| (!m.property_flags.lazily_allocated).then_some((i as u32, m)))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let heap_size = memory_type.heap().size();
|
let heap_size = device.physical_device().memory_properties().memory_heaps
|
||||||
|
[memory_type.heap_index as usize]
|
||||||
|
.size;
|
||||||
|
|
||||||
let mut allocs = Vec::new();
|
let mut allocs = Vec::new();
|
||||||
|
|
||||||
@ -1614,7 +1627,7 @@ mod tests {
|
|||||||
device.clone(),
|
device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: heap_size / 3,
|
allocation_size: heap_size / 3,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@ -1630,13 +1643,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn allocation_count() {
|
fn allocation_count() {
|
||||||
let (device, _) = gfx_dev_and_queue!();
|
let (device, _) = gfx_dev_and_queue!();
|
||||||
let memory_type = device.physical_device().memory_types().next().unwrap();
|
|
||||||
assert_eq!(*device.allocation_count().lock(), 0);
|
assert_eq!(*device.allocation_count().lock(), 0);
|
||||||
let _mem1 = DeviceMemory::allocate(
|
let _mem1 = DeviceMemory::allocate(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: 256,
|
allocation_size: 256,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index: 0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -1647,7 +1659,7 @@ mod tests {
|
|||||||
device.clone(),
|
device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: 256,
|
allocation_size: 256,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index: 0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
@ -21,8 +21,8 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//! // Enumerating memory heaps.
|
//! // Enumerating memory heaps.
|
||||||
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
||||||
//! for heap in physical_device.memory_heaps() {
|
//! for (index, heap) in physical_device.memory_properties().memory_heaps.iter().enumerate() {
|
||||||
//! println!("Heap #{:?} has a capacity of {:?} bytes", heap.id(), heap.size());
|
//! println!("Heap #{:?} has a capacity of {:?} bytes", index, heap.size);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -38,10 +38,10 @@
|
|||||||
//! ```
|
//! ```
|
||||||
//! // Enumerating memory types.
|
//! // Enumerating memory types.
|
||||||
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
//! # let physical_device: vulkano::device::physical::PhysicalDevice = return;
|
||||||
//! for ty in physical_device.memory_types() {
|
//! for ty in physical_device.memory_properties().memory_types.iter() {
|
||||||
//! println!("Memory type belongs to heap #{:?}", ty.heap().id());
|
//! println!("Memory type belongs to heap #{:?}", ty.heap_index);
|
||||||
//! println!("Host-accessible: {:?}", ty.is_host_visible());
|
//! println!("Host-accessible: {:?}", ty.property_flags.host_visible);
|
||||||
//! println!("Device-local: {:?}", ty.is_device_local());
|
//! println!("Device-local: {:?}", ty.property_flags.device_local);
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -69,13 +69,13 @@
|
|||||||
//!
|
//!
|
||||||
//! # let device: std::sync::Arc<vulkano::device::Device> = return;
|
//! # let device: std::sync::Arc<vulkano::device::Device> = return;
|
||||||
//! // Taking the first memory type for the sake of this example.
|
//! // Taking the first memory type for the sake of this example.
|
||||||
//! let memory_type = device.physical_device().memory_types().next().unwrap();
|
//! let memory_type_index = 0;
|
||||||
//!
|
//!
|
||||||
//! let memory = DeviceMemory::allocate(
|
//! let memory = DeviceMemory::allocate(
|
||||||
//! device.clone(),
|
//! device.clone(),
|
||||||
//! MemoryAllocateInfo {
|
//! MemoryAllocateInfo {
|
||||||
//! allocation_size: 1024,
|
//! allocation_size: 1024,
|
||||||
//! memory_type_index: memory_type.id(),
|
//! memory_type_index,
|
||||||
//! ..Default::default()
|
//! ..Default::default()
|
||||||
//! },
|
//! },
|
||||||
//! ).expect("Failed to allocate memory");
|
//! ).expect("Failed to allocate memory");
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{physical::MemoryType, Device},
|
device::Device,
|
||||||
instance::Instance,
|
|
||||||
memory::{
|
memory::{
|
||||||
device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError,
|
device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError,
|
||||||
MappedDeviceMemory,
|
MappedDeviceMemory,
|
||||||
@ -23,7 +22,7 @@ use std::{cmp, ops::Range, sync::Arc};
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StandardHostVisibleMemoryTypePool {
|
pub struct StandardHostVisibleMemoryTypePool {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
memory_type: u32,
|
memory_type_index: u32,
|
||||||
// TODO: obviously very inefficient
|
// TODO: obviously very inefficient
|
||||||
occupied: Mutex<Vec<(Arc<MappedDeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
occupied: Mutex<Vec<(Arc<MappedDeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
||||||
}
|
}
|
||||||
@ -33,27 +32,21 @@ impl StandardHostVisibleMemoryTypePool {
|
|||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panic
|
||||||
///
|
///
|
||||||
/// - Panics if the `device` and `memory_type` don't belong to the same physical device.
|
/// - Panics if `memory_type_index` is out of range.
|
||||||
/// - Panics if the memory type is not host-visible.
|
/// - Panics if `memory_type_index` refers to a memory type that is not host-visible.
|
||||||
///
|
///
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
memory_type: MemoryType,
|
memory_type_index: u32,
|
||||||
) -> Arc<StandardHostVisibleMemoryTypePool> {
|
) -> Arc<StandardHostVisibleMemoryTypePool> {
|
||||||
assert_eq!(
|
let memory_type =
|
||||||
&**device.physical_device().instance() as *const Instance,
|
&device.physical_device().memory_properties().memory_types[memory_type_index as usize];
|
||||||
&**memory_type.physical_device().instance() as *const Instance
|
assert!(memory_type.property_flags.host_visible);
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
device.physical_device().index(),
|
|
||||||
memory_type.physical_device().index()
|
|
||||||
);
|
|
||||||
assert!(memory_type.is_host_visible());
|
|
||||||
|
|
||||||
Arc::new(StandardHostVisibleMemoryTypePool {
|
Arc::new(StandardHostVisibleMemoryTypePool {
|
||||||
device,
|
device,
|
||||||
memory_type: memory_type.id(),
|
memory_type_index,
|
||||||
occupied: Mutex::new(Vec::new()),
|
occupied: Mutex::new(Vec::new()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -120,7 +113,7 @@ impl StandardHostVisibleMemoryTypePool {
|
|||||||
self.device.clone(),
|
self.device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size,
|
allocation_size,
|
||||||
memory_type_index: self.memory_type().id(),
|
memory_type_index: self.memory_type_index,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
@ -143,13 +136,10 @@ impl StandardHostVisibleMemoryTypePool {
|
|||||||
&self.device
|
&self.device
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the memory type this pool operates on.
|
/// Returns the index of the memory type this pool operates on.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn memory_type(&self) -> MemoryType {
|
pub fn memory_type_index(&self) -> u32 {
|
||||||
self.device
|
self.memory_type_index
|
||||||
.physical_device()
|
|
||||||
.memory_type_by_id(self.memory_type)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,34 +33,40 @@ mod pool;
|
|||||||
// the pool. This prevents the pool from overallocating a significant amount of memory.
|
// the pool. This prevents the pool from overallocating a significant amount of memory.
|
||||||
const MAX_POOL_ALLOC: DeviceSize = 256 * 1024 * 1024;
|
const MAX_POOL_ALLOC: DeviceSize = 256 * 1024 * 1024;
|
||||||
|
|
||||||
fn choose_allocation_memory_type<'s, F>(
|
fn choose_allocation_memory_type<F>(
|
||||||
device: &'s Arc<Device>,
|
device: &Arc<Device>,
|
||||||
requirements: &MemoryRequirements,
|
requirements: &MemoryRequirements,
|
||||||
mut filter: F,
|
mut filter: F,
|
||||||
map: MappingRequirement,
|
map: MappingRequirement,
|
||||||
) -> MemoryType<'s>
|
) -> u32
|
||||||
where
|
where
|
||||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||||
{
|
{
|
||||||
let mem_ty = {
|
let mem_ty = {
|
||||||
let mut filter = |ty: MemoryType| {
|
let mut filter = |ty: &MemoryType| {
|
||||||
if map == MappingRequirement::Map && !ty.is_host_visible() {
|
if map == MappingRequirement::Map && !ty.property_flags.host_visible {
|
||||||
return AllocFromRequirementsFilter::Forbidden;
|
return AllocFromRequirementsFilter::Forbidden;
|
||||||
}
|
}
|
||||||
filter(ty)
|
filter(ty)
|
||||||
};
|
};
|
||||||
let first_loop = device
|
let first_loop = device
|
||||||
.physical_device()
|
.physical_device()
|
||||||
.memory_types()
|
.memory_properties()
|
||||||
.map(|t| (t, AllocFromRequirementsFilter::Preferred));
|
.memory_types
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, t)| (i as u32, t, AllocFromRequirementsFilter::Preferred));
|
||||||
let second_loop = device
|
let second_loop = device
|
||||||
.physical_device()
|
.physical_device()
|
||||||
.memory_types()
|
.memory_properties()
|
||||||
.map(|t| (t, AllocFromRequirementsFilter::Allowed));
|
.memory_types
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(i, t)| (i as u32, t, AllocFromRequirementsFilter::Allowed));
|
||||||
first_loop
|
first_loop
|
||||||
.chain(second_loop)
|
.chain(second_loop)
|
||||||
.filter(|&(t, _)| (requirements.memory_type_bits & (1 << t.id())) != 0)
|
.filter(|(i, _, _)| (requirements.memory_type_bits & (1 << *i)) != 0)
|
||||||
.find(|&(t, rq)| filter(t) == rq)
|
.find(|&(_, t, rq)| filter(t) == rq)
|
||||||
.expect("Couldn't find a memory type to allocate from")
|
.expect("Couldn't find a memory type to allocate from")
|
||||||
.0
|
.0
|
||||||
};
|
};
|
||||||
@ -78,17 +84,17 @@ pub(crate) fn alloc_dedicated_with_exportable_fd<F>(
|
|||||||
filter: F,
|
filter: F,
|
||||||
) -> Result<PotentialDedicatedAllocation<StandardMemoryPoolAlloc>, DeviceMemoryAllocationError>
|
) -> Result<PotentialDedicatedAllocation<StandardMemoryPoolAlloc>, DeviceMemoryAllocationError>
|
||||||
where
|
where
|
||||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||||
{
|
{
|
||||||
assert!(device.enabled_extensions().khr_external_memory_fd);
|
assert!(device.enabled_extensions().khr_external_memory_fd);
|
||||||
assert!(device.enabled_extensions().khr_external_memory);
|
assert!(device.enabled_extensions().khr_external_memory);
|
||||||
|
|
||||||
let memory_type = choose_allocation_memory_type(&device, requirements, filter, map);
|
let memory_type_index = choose_allocation_memory_type(&device, requirements, filter, map);
|
||||||
let memory = DeviceMemory::allocate(
|
let memory = DeviceMemory::allocate(
|
||||||
device.clone(),
|
device,
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: requirements.size,
|
allocation_size: requirements.size,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index,
|
||||||
export_handle_types: ExternalMemoryHandleTypes {
|
export_handle_types: ExternalMemoryHandleTypes {
|
||||||
opaque_fd: true,
|
opaque_fd: true,
|
||||||
..ExternalMemoryHandleTypes::empty()
|
..ExternalMemoryHandleTypes::empty()
|
||||||
@ -134,7 +140,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
|||||||
///
|
///
|
||||||
fn alloc_generic(
|
fn alloc_generic(
|
||||||
&self,
|
&self,
|
||||||
ty: MemoryType,
|
memory_type_index: u32,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
alignment: DeviceSize,
|
alignment: DeviceSize,
|
||||||
layout: AllocLayout,
|
layout: AllocLayout,
|
||||||
@ -179,15 +185,16 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
|||||||
filter: F,
|
filter: F,
|
||||||
) -> Result<PotentialDedicatedAllocation<Self::Alloc>, DeviceMemoryAllocationError>
|
) -> Result<PotentialDedicatedAllocation<Self::Alloc>, DeviceMemoryAllocationError>
|
||||||
where
|
where
|
||||||
F: FnMut(MemoryType) -> AllocFromRequirementsFilter,
|
F: FnMut(&MemoryType) -> AllocFromRequirementsFilter,
|
||||||
{
|
{
|
||||||
// Choose a suitable memory type.
|
// Choose a suitable memory type.
|
||||||
let memory_type = choose_allocation_memory_type(self.device(), requirements, filter, map);
|
let memory_type_index =
|
||||||
|
choose_allocation_memory_type(self.device(), requirements, filter, map);
|
||||||
|
|
||||||
// Redirect to `self.alloc_generic` if we don't perform a dedicated allocation.
|
// Redirect to `self.alloc_generic` if we don't perform a dedicated allocation.
|
||||||
if !requirements.prefer_dedicated && requirements.size <= MAX_POOL_ALLOC {
|
if !requirements.prefer_dedicated && requirements.size <= MAX_POOL_ALLOC {
|
||||||
let alloc = self.alloc_generic(
|
let alloc = self.alloc_generic(
|
||||||
memory_type,
|
memory_type_index,
|
||||||
requirements.size,
|
requirements.size,
|
||||||
requirements.alignment,
|
requirements.alignment,
|
||||||
layout,
|
layout,
|
||||||
@ -197,7 +204,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
|||||||
}
|
}
|
||||||
if dedicated_allocation.is_none() {
|
if dedicated_allocation.is_none() {
|
||||||
let alloc = self.alloc_generic(
|
let alloc = self.alloc_generic(
|
||||||
memory_type,
|
memory_type_index,
|
||||||
requirements.size,
|
requirements.size,
|
||||||
requirements.alignment,
|
requirements.alignment,
|
||||||
layout,
|
layout,
|
||||||
@ -211,7 +218,7 @@ pub unsafe trait MemoryPool: DeviceOwned {
|
|||||||
self.device().clone(),
|
self.device().clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size: requirements.size,
|
allocation_size: requirements.size,
|
||||||
memory_type_index: memory_type.id(),
|
memory_type_index,
|
||||||
dedicated_allocation,
|
dedicated_allocation,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{physical::MemoryType, Device},
|
device::Device,
|
||||||
instance::Instance,
|
|
||||||
memory::{device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError},
|
memory::{device_memory::MemoryAllocateInfo, DeviceMemory, DeviceMemoryAllocationError},
|
||||||
DeviceSize,
|
DeviceSize,
|
||||||
};
|
};
|
||||||
@ -20,7 +19,7 @@ use std::{cmp, ops::Range, sync::Arc};
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StandardNonHostVisibleMemoryTypePool {
|
pub struct StandardNonHostVisibleMemoryTypePool {
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
memory_type: u32,
|
memory_type_index: u32,
|
||||||
// TODO: obviously very inefficient
|
// TODO: obviously very inefficient
|
||||||
occupied: Mutex<Vec<(Arc<DeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
occupied: Mutex<Vec<(Arc<DeviceMemory>, Vec<Range<DeviceSize>>)>>,
|
||||||
}
|
}
|
||||||
@ -30,25 +29,18 @@ impl StandardNonHostVisibleMemoryTypePool {
|
|||||||
///
|
///
|
||||||
/// # Panic
|
/// # Panic
|
||||||
///
|
///
|
||||||
/// - Panics if the `device` and `memory_type` don't belong to the same physical device.
|
/// - Panics if `memory_type_index` is out of range.
|
||||||
///
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: Arc<Device>,
|
device: Arc<Device>,
|
||||||
memory_type: MemoryType,
|
memory_type_index: u32,
|
||||||
) -> Arc<StandardNonHostVisibleMemoryTypePool> {
|
) -> Arc<StandardNonHostVisibleMemoryTypePool> {
|
||||||
assert_eq!(
|
let _ =
|
||||||
&**device.physical_device().instance() as *const Instance,
|
&device.physical_device().memory_properties().memory_types[memory_type_index as usize];
|
||||||
&**memory_type.physical_device().instance() as *const Instance
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
device.physical_device().index(),
|
|
||||||
memory_type.physical_device().index()
|
|
||||||
);
|
|
||||||
|
|
||||||
Arc::new(StandardNonHostVisibleMemoryTypePool {
|
Arc::new(StandardNonHostVisibleMemoryTypePool {
|
||||||
device,
|
device,
|
||||||
memory_type: memory_type.id(),
|
memory_type_index,
|
||||||
occupied: Mutex::new(Vec::new()),
|
occupied: Mutex::new(Vec::new()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -115,7 +107,7 @@ impl StandardNonHostVisibleMemoryTypePool {
|
|||||||
self.device.clone(),
|
self.device.clone(),
|
||||||
MemoryAllocateInfo {
|
MemoryAllocateInfo {
|
||||||
allocation_size,
|
allocation_size,
|
||||||
memory_type_index: self.memory_type().id(),
|
memory_type_index: self.memory_type_index,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
@ -131,19 +123,10 @@ impl StandardNonHostVisibleMemoryTypePool {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the device this pool operates on.
|
/// Returns the index of the memory type this pool operates on.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn device(&self) -> &Arc<Device> {
|
pub fn memory_type_index(&self) -> u32 {
|
||||||
&self.device
|
self.memory_type_index
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the memory type this pool operates on.
|
|
||||||
#[inline]
|
|
||||||
pub fn memory_type(&self) -> MemoryType {
|
|
||||||
self.device
|
|
||||||
.physical_device()
|
|
||||||
.memory_type_by_id(self.memory_type)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
// according to those terms.
|
// according to those terms.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{physical::MemoryType, Device, DeviceOwned},
|
device::{Device, DeviceOwned},
|
||||||
memory::{
|
memory::{
|
||||||
pool::{
|
pool::{
|
||||||
AllocLayout, MappingRequirement, MemoryPool, MemoryPoolAlloc,
|
AllocLayout, MappingRequirement, MemoryPool, MemoryPoolAlloc,
|
||||||
@ -37,7 +37,11 @@ impl StandardMemoryPool {
|
|||||||
/// Creates a new pool.
|
/// Creates a new pool.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(device: Arc<Device>) -> Arc<StandardMemoryPool> {
|
pub fn new(device: Arc<Device>) -> Arc<StandardMemoryPool> {
|
||||||
let cap = device.physical_device().memory_types().len();
|
let cap = device
|
||||||
|
.physical_device()
|
||||||
|
.memory_properties()
|
||||||
|
.memory_types
|
||||||
|
.len();
|
||||||
|
|
||||||
Arc::new(StandardMemoryPool {
|
Arc::new(StandardMemoryPool {
|
||||||
device,
|
device,
|
||||||
@ -48,7 +52,7 @@ impl StandardMemoryPool {
|
|||||||
|
|
||||||
fn generic_allocation(
|
fn generic_allocation(
|
||||||
mem_pool: Arc<StandardMemoryPool>,
|
mem_pool: Arc<StandardMemoryPool>,
|
||||||
memory_type: MemoryType,
|
memory_type_index: u32,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
alignment: DeviceSize,
|
alignment: DeviceSize,
|
||||||
layout: AllocLayout,
|
layout: AllocLayout,
|
||||||
@ -56,10 +60,19 @@ fn generic_allocation(
|
|||||||
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
||||||
let mut pools = mem_pool.pools.lock();
|
let mut pools = mem_pool.pools.lock();
|
||||||
|
|
||||||
let memory_type_host_visible = memory_type.is_host_visible();
|
let memory_properties = mem_pool.device().physical_device().memory_properties();
|
||||||
|
let memory_type = memory_properties
|
||||||
|
.memory_types
|
||||||
|
.get(memory_type_index as usize)
|
||||||
|
.ok_or(DeviceMemoryAllocationError::MemoryTypeIndexOutOfRange {
|
||||||
|
memory_type_index,
|
||||||
|
memory_type_count: memory_properties.memory_types.len() as u32,
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let memory_type_host_visible = memory_type.property_flags.host_visible;
|
||||||
assert!(memory_type_host_visible || map == MappingRequirement::DoNotMap);
|
assert!(memory_type_host_visible || map == MappingRequirement::DoNotMap);
|
||||||
|
|
||||||
match pools.entry((memory_type.id(), layout, map)) {
|
match pools.entry((memory_type_index, layout, map)) {
|
||||||
Entry::Occupied(entry) => match *entry.get() {
|
Entry::Occupied(entry) => match *entry.get() {
|
||||||
Pool::HostVisible(ref pool) => {
|
Pool::HostVisible(ref pool) => {
|
||||||
let alloc = pool.alloc(size, alignment)?;
|
let alloc = pool.alloc(size, alignment)?;
|
||||||
@ -81,8 +94,10 @@ fn generic_allocation(
|
|||||||
|
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
if memory_type_host_visible {
|
if memory_type_host_visible {
|
||||||
let pool =
|
let pool = StandardHostVisibleMemoryTypePool::new(
|
||||||
StandardHostVisibleMemoryTypePool::new(mem_pool.device.clone(), memory_type);
|
mem_pool.device.clone(),
|
||||||
|
memory_type_index,
|
||||||
|
);
|
||||||
entry.insert(Pool::HostVisible(pool.clone()));
|
entry.insert(Pool::HostVisible(pool.clone()));
|
||||||
let alloc = pool.alloc(size, alignment)?;
|
let alloc = pool.alloc(size, alignment)?;
|
||||||
let inner = StandardMemoryPoolAllocInner::HostVisible(alloc);
|
let inner = StandardMemoryPoolAllocInner::HostVisible(alloc);
|
||||||
@ -91,8 +106,10 @@ fn generic_allocation(
|
|||||||
_pool: mem_pool.clone(),
|
_pool: mem_pool.clone(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let pool =
|
let pool = StandardNonHostVisibleMemoryTypePool::new(
|
||||||
StandardNonHostVisibleMemoryTypePool::new(mem_pool.device.clone(), memory_type);
|
mem_pool.device.clone(),
|
||||||
|
memory_type_index,
|
||||||
|
);
|
||||||
entry.insert(Pool::NonHostVisible(pool.clone()));
|
entry.insert(Pool::NonHostVisible(pool.clone()));
|
||||||
let alloc = pool.alloc(size, alignment)?;
|
let alloc = pool.alloc(size, alignment)?;
|
||||||
let inner = StandardMemoryPoolAllocInner::NonHostVisible(alloc);
|
let inner = StandardMemoryPoolAllocInner::NonHostVisible(alloc);
|
||||||
@ -110,13 +127,20 @@ unsafe impl MemoryPool for Arc<StandardMemoryPool> {
|
|||||||
|
|
||||||
fn alloc_generic(
|
fn alloc_generic(
|
||||||
&self,
|
&self,
|
||||||
memory_type: MemoryType,
|
memory_type_index: u32,
|
||||||
size: DeviceSize,
|
size: DeviceSize,
|
||||||
alignment: DeviceSize,
|
alignment: DeviceSize,
|
||||||
layout: AllocLayout,
|
layout: AllocLayout,
|
||||||
map: MappingRequirement,
|
map: MappingRequirement,
|
||||||
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
) -> Result<StandardMemoryPoolAlloc, DeviceMemoryAllocationError> {
|
||||||
generic_allocation(self.clone(), memory_type, size, alignment, layout, map)
|
generic_allocation(
|
||||||
|
self.clone(),
|
||||||
|
memory_type_index,
|
||||||
|
size,
|
||||||
|
alignment,
|
||||||
|
layout,
|
||||||
|
map,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ mod tests {
|
|||||||
|
|
||||||
let mut cbb = AutoCommandBufferBuilder::primary(
|
let mut cbb = AutoCommandBufferBuilder::primary(
|
||||||
device.clone(),
|
device.clone(),
|
||||||
queue.family(),
|
queue.queue_family_index(),
|
||||||
CommandBufferUsage::OneTimeSubmit,
|
CommandBufferUsage::OneTimeSubmit,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -29,8 +29,8 @@
|
|||||||
#![allow(unused_variables)] // TODO: this module isn't finished
|
#![allow(unused_variables)] // TODO: this module isn't finished
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
device::physical::PhysicalDevice, instance::Instance, swapchain::SupportedSurfaceTransforms,
|
device::physical::PhysicalDevice, swapchain::SupportedSurfaceTransforms, OomError, VulkanError,
|
||||||
OomError, VulkanError, VulkanObject,
|
VulkanObject,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
ffi::CStr,
|
ffi::CStr,
|
||||||
@ -46,8 +46,7 @@ use std::{
|
|||||||
// TODO: plane capabilities
|
// TODO: plane capabilities
|
||||||
// TODO: store properties in the instance?
|
// TODO: store properties in the instance?
|
||||||
pub struct DisplayPlane {
|
pub struct DisplayPlane {
|
||||||
instance: Arc<Instance>,
|
physical_device: Arc<PhysicalDevice>,
|
||||||
physical_device: usize,
|
|
||||||
index: u32,
|
index: u32,
|
||||||
properties: ash::vk::DisplayPlanePropertiesKHR,
|
properties: ash::vk::DisplayPlanePropertiesKHR,
|
||||||
supported_displays: Vec<ash::vk::DisplayKHR>,
|
supported_displays: Vec<ash::vk::DisplayKHR>,
|
||||||
@ -55,17 +54,19 @@ pub struct DisplayPlane {
|
|||||||
|
|
||||||
impl DisplayPlane {
|
impl DisplayPlane {
|
||||||
/// See the docs of enumerate().
|
/// See the docs of enumerate().
|
||||||
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<DisplayPlane>, OomError> {
|
pub fn enumerate_raw(
|
||||||
let fns = device.instance().fns();
|
physical_device: Arc<PhysicalDevice>,
|
||||||
|
) -> Result<IntoIter<DisplayPlane>, OomError> {
|
||||||
|
let fns = physical_device.instance().fns();
|
||||||
|
|
||||||
assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||||
|
|
||||||
let display_plane_properties = unsafe {
|
let display_plane_properties = unsafe {
|
||||||
loop {
|
loop {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
(fns.khr_display
|
(fns.khr_display
|
||||||
.get_physical_device_display_plane_properties_khr)(
|
.get_physical_device_display_plane_properties_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
&mut count,
|
&mut count,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
)
|
)
|
||||||
@ -76,7 +77,7 @@ impl DisplayPlane {
|
|||||||
let result = (fns
|
let result = (fns
|
||||||
.khr_display
|
.khr_display
|
||||||
.get_physical_device_display_plane_properties_khr)(
|
.get_physical_device_display_plane_properties_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
&mut count,
|
&mut count,
|
||||||
properties.as_mut_ptr(),
|
properties.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
@ -100,7 +101,7 @@ impl DisplayPlane {
|
|||||||
loop {
|
loop {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
(fns.khr_display.get_display_plane_supported_displays_khr)(
|
(fns.khr_display.get_display_plane_supported_displays_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
index as u32,
|
index as u32,
|
||||||
&mut count,
|
&mut count,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
@ -111,7 +112,7 @@ impl DisplayPlane {
|
|||||||
|
|
||||||
let mut displays = Vec::with_capacity(count as usize);
|
let mut displays = Vec::with_capacity(count as usize);
|
||||||
let result = (fns.khr_display.get_display_plane_supported_displays_khr)(
|
let result = (fns.khr_display.get_display_plane_supported_displays_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
index as u32,
|
index as u32,
|
||||||
&mut count,
|
&mut count,
|
||||||
displays.as_mut_ptr(),
|
displays.as_mut_ptr(),
|
||||||
@ -129,8 +130,7 @@ impl DisplayPlane {
|
|||||||
};
|
};
|
||||||
|
|
||||||
DisplayPlane {
|
DisplayPlane {
|
||||||
instance: device.instance().clone(),
|
physical_device: physical_device.clone(),
|
||||||
physical_device: device.index(),
|
|
||||||
index: index as u32,
|
index: index as u32,
|
||||||
properties: prop,
|
properties: prop,
|
||||||
supported_displays,
|
supported_displays,
|
||||||
@ -148,14 +148,14 @@ impl DisplayPlane {
|
|||||||
///
|
///
|
||||||
// TODO: move iterator creation here from raw constructor?
|
// TODO: move iterator creation here from raw constructor?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enumerate(device: PhysicalDevice) -> IntoIter<DisplayPlane> {
|
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<DisplayPlane> {
|
||||||
DisplayPlane::enumerate_raw(device).unwrap()
|
DisplayPlane::enumerate_raw(physical_device).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the physical device that was used to create this display.
|
/// Returns the physical device that was used to create this display.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn physical_device(&self) -> PhysicalDevice {
|
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
&self.physical_device
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index of the plane.
|
/// Returns the index of the plane.
|
||||||
@ -182,22 +182,23 @@ impl DisplayPlane {
|
|||||||
// TODO: store properties in the instance?
|
// TODO: store properties in the instance?
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Display {
|
pub struct Display {
|
||||||
instance: Arc<Instance>,
|
physical_device: Arc<PhysicalDevice>,
|
||||||
physical_device: usize,
|
|
||||||
properties: Arc<ash::vk::DisplayPropertiesKHR>, // TODO: Arc because struct isn't clone
|
properties: Arc<ash::vk::DisplayPropertiesKHR>, // TODO: Arc because struct isn't clone
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display {
|
impl Display {
|
||||||
/// See the docs of enumerate().
|
/// See the docs of enumerate().
|
||||||
pub fn enumerate_raw(device: PhysicalDevice) -> Result<IntoIter<Display>, OomError> {
|
pub fn enumerate_raw(
|
||||||
let fns = device.instance().fns();
|
physical_device: Arc<PhysicalDevice>,
|
||||||
assert!(device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
) -> Result<IntoIter<Display>, OomError> {
|
||||||
|
let fns = physical_device.instance().fns();
|
||||||
|
assert!(physical_device.instance().enabled_extensions().khr_display); // TODO: return error instead
|
||||||
|
|
||||||
let display_properties = unsafe {
|
let display_properties = unsafe {
|
||||||
loop {
|
loop {
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
(fns.khr_display.get_physical_device_display_properties_khr)(
|
(fns.khr_display.get_physical_device_display_properties_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
&mut count,
|
&mut count,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
)
|
)
|
||||||
@ -206,7 +207,7 @@ impl Display {
|
|||||||
|
|
||||||
let mut properties = Vec::with_capacity(count as usize);
|
let mut properties = Vec::with_capacity(count as usize);
|
||||||
let result = (fns.khr_display.get_physical_device_display_properties_khr)(
|
let result = (fns.khr_display.get_physical_device_display_properties_khr)(
|
||||||
device.internal_object(),
|
physical_device.internal_object(),
|
||||||
&mut count,
|
&mut count,
|
||||||
properties.as_mut_ptr(),
|
properties.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
@ -225,8 +226,7 @@ impl Display {
|
|||||||
Ok(display_properties
|
Ok(display_properties
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|prop| Display {
|
.map(|prop| Display {
|
||||||
instance: device.instance().clone(),
|
physical_device: physical_device.clone(),
|
||||||
physical_device: device.index(),
|
|
||||||
properties: Arc::new(prop),
|
properties: Arc::new(prop),
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
@ -241,8 +241,8 @@ impl Display {
|
|||||||
///
|
///
|
||||||
// TODO: move iterator creation here from raw constructor?
|
// TODO: move iterator creation here from raw constructor?
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn enumerate(device: PhysicalDevice) -> IntoIter<Display> {
|
pub fn enumerate(physical_device: Arc<PhysicalDevice>) -> IntoIter<Display> {
|
||||||
Display::enumerate_raw(device).unwrap()
|
Display::enumerate_raw(physical_device).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the name of the display.
|
/// Returns the name of the display.
|
||||||
@ -257,8 +257,8 @@ impl Display {
|
|||||||
|
|
||||||
/// Returns the physical device that was used to create this display.
|
/// Returns the physical device that was used to create this display.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn physical_device(&self) -> PhysicalDevice {
|
pub fn physical_device(&self) -> &Arc<PhysicalDevice> {
|
||||||
PhysicalDevice::from_index(&self.instance, self.physical_device).unwrap()
|
&self.physical_device
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the physical dimensions of the display in millimeters.
|
/// Returns the physical dimensions of the display in millimeters.
|
||||||
@ -298,7 +298,7 @@ impl Display {
|
|||||||
|
|
||||||
/// See the docs of display_modes().
|
/// See the docs of display_modes().
|
||||||
pub fn display_modes_raw(&self) -> Result<IntoIter<DisplayMode>, OomError> {
|
pub fn display_modes_raw(&self) -> Result<IntoIter<DisplayMode>, OomError> {
|
||||||
let fns = self.instance.fns();
|
let fns = self.physical_device.instance().fns();
|
||||||
|
|
||||||
let mode_properties = unsafe {
|
let mode_properties = unsafe {
|
||||||
loop {
|
loop {
|
||||||
|
@ -452,19 +452,28 @@ impl<W> Swapchain<W> {
|
|||||||
|
|
||||||
match image_sharing {
|
match image_sharing {
|
||||||
Sharing::Exclusive => (),
|
Sharing::Exclusive => (),
|
||||||
Sharing::Concurrent(ids) => {
|
Sharing::Concurrent(queue_family_indices) => {
|
||||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278
|
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01278
|
||||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
||||||
ids.sort_unstable();
|
queue_family_indices.sort_unstable();
|
||||||
ids.dedup();
|
queue_family_indices.dedup();
|
||||||
assert!(ids.len() >= 2);
|
assert!(queue_family_indices.len() >= 2);
|
||||||
|
|
||||||
for &id in ids.iter() {
|
for &queue_family_index in queue_family_indices.iter() {
|
||||||
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
// VUID-VkSwapchainCreateInfoKHR-imageSharingMode-01428
|
||||||
if device.physical_device().queue_family_by_id(id).is_none() {
|
if queue_family_index
|
||||||
return Err(SwapchainCreationError::ImageSharingInvalidQueueFamilyId {
|
>= device.physical_device().queue_family_properties().len() as u32
|
||||||
id,
|
{
|
||||||
});
|
return Err(
|
||||||
|
SwapchainCreationError::ImageSharingQueueFamilyIndexOutOfRange {
|
||||||
|
queue_family_index,
|
||||||
|
queue_family_count: device
|
||||||
|
.physical_device()
|
||||||
|
.queue_family_properties()
|
||||||
|
.len()
|
||||||
|
as u32,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1111,8 +1120,11 @@ pub enum SwapchainCreationError {
|
|||||||
ImageFormatPropertiesNotSupported,
|
ImageFormatPropertiesNotSupported,
|
||||||
|
|
||||||
/// The provided `image_sharing` was set to `Concurrent`, but one of the specified queue family
|
/// The provided `image_sharing` was set to `Concurrent`, but one of the specified queue family
|
||||||
/// ids was not valid.
|
/// indices was out of range.
|
||||||
ImageSharingInvalidQueueFamilyId { id: u32 },
|
ImageSharingQueueFamilyIndexOutOfRange {
|
||||||
|
queue_family_index: u32,
|
||||||
|
queue_family_count: u32,
|
||||||
|
},
|
||||||
|
|
||||||
/// The provided `image_usage` has fields set that are not supported by the surface for this
|
/// The provided `image_usage` has fields set that are not supported by the surface for this
|
||||||
/// device.
|
/// device.
|
||||||
@ -1204,10 +1216,10 @@ impl Display for SwapchainCreationError {
|
|||||||
f,
|
f,
|
||||||
"the provided image parameters are not supported as queried from `image_format_properties`",
|
"the provided image parameters are not supported as queried from `image_format_properties`",
|
||||||
),
|
),
|
||||||
Self::ImageSharingInvalidQueueFamilyId { id } => write!(
|
Self::ImageSharingQueueFamilyIndexOutOfRange { queue_family_index, queue_family_count: _ } => write!(
|
||||||
f,
|
f,
|
||||||
"the provided `image_sharing` was set to `Concurrent`, but one of the specified queue family ids ({}) was not valid",
|
"the provided `image_sharing` was set to `Concurrent`, but one of the specified queue family indices ({}) was out of range",
|
||||||
id,
|
queue_family_index,
|
||||||
),
|
),
|
||||||
Self::ImageUsageNotSupported { .. } => write!(
|
Self::ImageUsageNotSupported { .. } => write!(
|
||||||
f,
|
f,
|
||||||
@ -1266,6 +1278,7 @@ impl From<SurfacePropertiesError> for SwapchainCreationError {
|
|||||||
SurfacePropertiesError::OomError(err) => Self::OomError(err),
|
SurfacePropertiesError::OomError(err) => Self::OomError(err),
|
||||||
SurfacePropertiesError::SurfaceLost => Self::SurfaceLost,
|
SurfacePropertiesError::SurfaceLost => Self::SurfaceLost,
|
||||||
SurfacePropertiesError::NotSupported => unreachable!(),
|
SurfacePropertiesError::NotSupported => unreachable!(),
|
||||||
|
SurfacePropertiesError::QueueFamilyIndexOutOfRange { .. } => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,12 @@ impl<'a> From<&'a Arc<Queue>> for SharingMode {
|
|||||||
impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
|
impl<'a> From<&'a [&'a Arc<Queue>]> for SharingMode {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
|
fn from(queues: &'a [&'a Arc<Queue>]) -> SharingMode {
|
||||||
SharingMode::Concurrent(queues.iter().map(|queue| queue.family().id()).collect())
|
SharingMode::Concurrent(
|
||||||
|
queues
|
||||||
|
.iter()
|
||||||
|
.map(|queue| queue.queue_family_index())
|
||||||
|
.collect(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -501,9 +501,7 @@ impl From<OomError> for SemaphoreExportError {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{
|
use crate::{
|
||||||
device::{
|
device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo},
|
||||||
physical::PhysicalDevice, Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo,
|
|
||||||
},
|
|
||||||
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
instance::{Instance, InstanceCreateInfo, InstanceExtensions},
|
||||||
sync::{ExternalSemaphoreHandleTypes, Semaphore, SemaphoreCreateInfo},
|
sync::{ExternalSemaphoreHandleTypes, Semaphore, SemaphoreCreateInfo},
|
||||||
VulkanLibrary, VulkanObject,
|
VulkanLibrary, VulkanObject,
|
||||||
@ -554,8 +552,10 @@ mod tests {
|
|||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
let physical_device = PhysicalDevice::enumerate(&instance).next().unwrap();
|
let physical_device = match instance.enumerate_physical_devices() {
|
||||||
let queue_family = physical_device.queue_families().next().unwrap();
|
Ok(mut x) => x.next().unwrap(),
|
||||||
|
Err(_) => return,
|
||||||
|
};
|
||||||
|
|
||||||
let (device, _) = match Device::new(
|
let (device, _) = match Device::new(
|
||||||
physical_device,
|
physical_device,
|
||||||
@ -565,7 +565,10 @@ mod tests {
|
|||||||
khr_external_semaphore_fd: true,
|
khr_external_semaphore_fd: true,
|
||||||
..DeviceExtensions::empty()
|
..DeviceExtensions::empty()
|
||||||
},
|
},
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index: 0,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
|
@ -29,7 +29,7 @@ macro_rules! instance {
|
|||||||
/// Creates a device and a queue for graphics operations.
|
/// Creates a device and a queue for graphics operations.
|
||||||
macro_rules! gfx_dev_and_queue {
|
macro_rules! gfx_dev_and_queue {
|
||||||
($($feature:ident),*) => ({
|
($($feature:ident),*) => ({
|
||||||
use crate::device::physical::{PhysicalDevice, PhysicalDeviceType};
|
use crate::device::physical::PhysicalDeviceType;
|
||||||
use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
|
use crate::device::{Device, DeviceCreateInfo, DeviceExtensions, QueueCreateInfo};
|
||||||
use crate::device::Features;
|
use crate::device::Features;
|
||||||
|
|
||||||
@ -42,15 +42,18 @@ macro_rules! gfx_dev_and_queue {
|
|||||||
.. Features::empty()
|
.. Features::empty()
|
||||||
};
|
};
|
||||||
|
|
||||||
let select = PhysicalDevice::enumerate(&instance)
|
let select = match instance.enumerate_physical_devices() {
|
||||||
.filter(|&p| {
|
Ok(x) => x,
|
||||||
|
Err(_) => return,
|
||||||
|
}
|
||||||
|
.filter(|p| {
|
||||||
p.supported_extensions().contains(&enabled_extensions) &&
|
p.supported_extensions().contains(&enabled_extensions) &&
|
||||||
p.supported_features().contains(&enabled_features)
|
p.supported_features().contains(&enabled_features)
|
||||||
})
|
})
|
||||||
.filter_map(|p| {
|
.filter_map(|p| {
|
||||||
p.queue_families()
|
p.queue_family_properties().iter()
|
||||||
.find(|&q| q.supports_graphics())
|
.position(|q| q.queue_flags.graphics)
|
||||||
.map(|q| (p, q))
|
.map(|i| (p, i as u32))
|
||||||
})
|
})
|
||||||
.min_by_key(|(p, _)| {
|
.min_by_key(|(p, _)| {
|
||||||
match p.properties().device_type {
|
match p.properties().device_type {
|
||||||
@ -62,7 +65,7 @@ macro_rules! gfx_dev_and_queue {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let (physical_device, queue_family) = match select {
|
let (physical_device, queue_family_index) = match select {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
None => return,
|
None => return,
|
||||||
};
|
};
|
||||||
@ -70,7 +73,10 @@ macro_rules! gfx_dev_and_queue {
|
|||||||
let (device, mut queues) = match Device::new(
|
let (device, mut queues) = match Device::new(
|
||||||
physical_device,
|
physical_device,
|
||||||
DeviceCreateInfo {
|
DeviceCreateInfo {
|
||||||
queue_create_infos: vec![QueueCreateInfo::family(queue_family)],
|
queue_create_infos: vec![QueueCreateInfo {
|
||||||
|
queue_family_index,
|
||||||
|
..Default::default()
|
||||||
|
}],
|
||||||
enabled_extensions,
|
enabled_extensions,
|
||||||
enabled_features,
|
enabled_features,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
Loading…
Reference in New Issue
Block a user