Fix undefined behaviour on external semaphore & image creation; Fix wrong device chosen on hybrid graphics (#1783)

* Fix device memory missing p_next structures

* Fix exportable attachment image missing p_next; Fix mutable bit off

* Fix fd export for StorageImage

* Fix undefined behaviour on external semaphore & image creation

* Add uuid check on physical device creation

* Add rev specification to glium dependency
This commit is contained in:
Francisco Ayala Le Brun 2022-01-04 22:14:18 +01:00 committed by GitHub
parent 805c9d388e
commit adef9bd17a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 40 deletions

View File

@ -24,4 +24,4 @@ serde = { version = "1.0", features = ["derive"] }
ron = "0.7"
rand = "0.8.4"
glium = { git = "https://github.com/glium/glium.git" }
glium = { git = "https://github.com/glium/glium.git", rev = "60889a2" }

View File

@ -57,6 +57,15 @@ fn main() {
.build_surfaceless(&event_loop_gl)
.unwrap();
let hrb_vk = glutin::ContextBuilder::new()
.with_gl_debug_flag(true)
.with_gl(glutin::GlRequest::Latest)
.build_surfaceless(&event_loop_gl)
.unwrap();
let display =
glium::HeadlessRenderer::with_debug(hrb_vk, glium::debug::DebugCallbackBehavior::PrintAll)
.unwrap(); // Used for checking device and driver UUIDs
let (
device,
_instance,
@ -70,7 +79,7 @@ fn main() {
sampler,
pipeline,
vertex_buffer,
) = vk_setup();
) = vk_setup(display);
let image = StorageImage::new_with_exportable_fd(
device.clone(),
@ -323,7 +332,9 @@ struct Vertex {
vulkano::impl_vertex!(Vertex, position);
#[cfg(target_os = "linux")]
fn vk_setup() -> (
fn vk_setup(
display: glium::HeadlessRenderer,
) -> (
Arc<vulkano::device::Device>,
Arc<vulkano::instance::Instance>,
Arc<Swapchain<winit::window::Window>>,
@ -353,7 +364,7 @@ fn vk_setup() -> (
..InstanceExtensions::none()
}
.union(&required_extensions)),
vec!["VK_LAYER_KHRONOS_validation"],
vec![],
)
.unwrap();
@ -391,6 +402,13 @@ fn vk_setup() -> (
.find(|&q| q.supports_graphics() && surface.is_supported(q).unwrap_or(false))
.map(|q| (p, q))
})
.filter(|(p, _)| p.properties().driver_uuid.unwrap() == display.driver_uuid().unwrap())
.filter(|(p, _)| {
display
.device_uuids()
.unwrap()
.contains(&p.properties().device_uuid.unwrap())
})
.min_by_key(|(p, _)| match p.properties().device_type {
PhysicalDeviceType::DiscreteGpu => 0,
PhysicalDeviceType::IntegratedGpu => 1,

View File

@ -574,43 +574,48 @@ impl UnsafeImage {
}
// Everything now ok. Creating the image.
let image = {
let mut infos = ash::vk::ImageCreateInfo {
flags: flags.into(),
image_type: ty,
format: format.into(),
extent,
mip_levels: mipmaps,
array_layers: array_layers,
samples: num_samples.into(),
tiling: if linear_tiling {
ash::vk::ImageTiling::LINEAR
} else {
ash::vk::ImageTiling::OPTIMAL
},
usage: usage_bits,
sharing_mode: sh_mode,
queue_family_index_count: sh_indices.len() as u32,
p_queue_family_indices: sh_indices.as_ptr(),
initial_layout: if preinitialized_layout {
ash::vk::ImageLayout::PREINITIALIZED
} else {
ash::vk::ImageLayout::UNDEFINED
},
..Default::default()
};
let image = {
let mut infos_builder = ash::vk::ImageCreateInfo::builder()
.flags(flags.into())
.image_type(ty)
.format(format.into())
.extent(extent)
.mip_levels(mipmaps)
.array_layers(array_layers)
.samples(num_samples.into())
.tiling({
if linear_tiling {
ash::vk::ImageTiling::LINEAR
} else {
ash::vk::ImageTiling::OPTIMAL
}
})
.usage(usage_bits)
.sharing_mode(sh_mode)
.queue_family_indices(&sh_indices)
.initial_layout({
if preinitialized_layout {
ash::vk::ImageLayout::PREINITIALIZED
} else {
ash::vk::ImageLayout::UNDEFINED
}
});
let mut ext_image_create_info;
if let Some(mem_types) = external_mem_handle_type {
infos.p_next = std::mem::transmute(&ash::vk::ExternalMemoryImageCreateInfo {
ext_image_create_info = ash::vk::ExternalMemoryImageCreateInfo {
handle_types: mem_types.into(),
..Default::default()
});
};
infos_builder = infos_builder.push_next(&mut ext_image_create_info);
}
let mut output = MaybeUninit::uninit();
check_errors(fns.v1_0.create_image(
device.internal_object(),
&infos,
&infos_builder.build(),
ptr::null(),
output.as_mut_ptr(),
))?;

View File

@ -53,27 +53,27 @@ where
// TODO: Add support for VkExportSemaphoreWin32HandleInfoKHR
// TODO: Add suport for importable semaphores
pub struct SemaphoreBuilder<D = Arc<Device>>
pub struct SemaphoreBuilder<'a, D = Arc<Device>>
where
D: SafeDeref<Target = Device>,
{
device: D,
export_info: Option<ash::vk::ExportSemaphoreCreateInfo>,
create: ash::vk::SemaphoreCreateInfo,
create_builder: ash::vk::SemaphoreCreateInfoBuilder<'a>,
must_put_in_pool: bool,
}
impl<D> SemaphoreBuilder<D>
impl<'a, D> SemaphoreBuilder<'a, D>
where
D: SafeDeref<Target = Device>,
{
pub fn new(device: D) -> Self {
let create = ash::vk::SemaphoreCreateInfo::default();
let create_builder = ash::vk::SemaphoreCreateInfo::builder();
Self {
device,
export_info: None,
create,
create_builder,
must_put_in_pool: false,
}
}
@ -96,12 +96,11 @@ where
};
self.export_info = Some(export_info);
self.create.p_next = unsafe { std::mem::transmute(&export_info) };
self
}
pub fn build(self) -> Result<Semaphore<D>, SemaphoreError> {
pub fn build(mut self) -> Result<Semaphore<D>, SemaphoreError> {
if self.export_info.is_some()
&& !self
.device
@ -113,12 +112,17 @@ where
"khr_external_semaphore_capabilities",
))
} else {
let mut builder = self.create_builder;
if let Some(export_info) = self.export_info.as_mut() {
builder = builder.push_next(export_info);
}
let semaphore = unsafe {
let fns = self.device.fns();
let mut output = MaybeUninit::uninit();
check_errors(fns.v1_0.create_semaphore(
self.device.internal_object(),
&self.create,
&builder.build(),
ptr::null(),
output.as_mut_ptr(),
))?;