rutabaga: Introduce device id, remove physical index

Add a new identifier for a device, the "device id". This is a
combination of the device UUID + driver UUID. Reason for not only using
device UUID is that the spec calls out both must match:

https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#external-memory-handle-types-compatibility

We have also seen some less-ideal implementations of device UUID on
Windows that return mostly zero with a few bits set, so adding the
driver UUID should increase confidence.

physical_device_idx is removed.

BUG=b:244622199
TEST=presubmit & downstream

Change-Id: I8174227e3d4bcadf778b7a73c9f84bb475169326
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3926105
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Idan Raiter <idanr@google.com>
Reviewed-by: Dennis Kempin <denniskempin@google.com>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
This commit is contained in:
Idan Raiter 2022-09-29 09:24:17 -07:00 committed by crosvm LUCI
parent 9c019a9453
commit 466deb7a78
6 changed files with 49 additions and 29 deletions

View file

@ -736,7 +736,7 @@ impl VirtioGpu {
descriptor: export.os_handle,
handle_type: export.handle_type,
memory_idx: vulkan_info.memory_idx,
physical_device_idx: vulkan_info.physical_device_idx,
device_id: vulkan_info.device_id,
size: resource.size,
});
} else if export.handle_type != RUTABAGA_MEM_HANDLE_TYPE_OPAQUE_FD {

View file

@ -528,7 +528,9 @@ impl CrossDomainContext {
if let Some(ref vk_info) = reqs.vulkan_info {
response.memory_idx = vk_info.memory_idx as i32;
response.physical_device_idx = vk_info.physical_device_idx as i32;
// We return -1 for now since physical_device_idx is deprecated. If this backend is
// put back into action, it should be using device_id from the request instead.
response.physical_device_idx = -1;
}
if let Some(state) = &self.state {

View file

@ -76,7 +76,8 @@ pub struct stream_renderer_handle {
#[derive(Copy, Clone, Default)]
pub struct stream_renderer_vulkan_info {
pub memory_index: u32,
pub physical_device_index: u32,
pub device_uuid: [u8; 16],
pub driver_uuid: [u8; 16],
}
#[allow(non_camel_case_types)]
@ -315,7 +316,10 @@ impl Gfxstream {
Ok(VulkanInfo {
memory_idx: vulkan_info.memory_index,
physical_device_idx: vulkan_info.physical_device_index,
device_id: DeviceId {
device_uuid: vulkan_info.device_uuid,
driver_uuid: vulkan_info.driver_uuid,
},
})
}

View file

@ -55,7 +55,7 @@ use crate::rutabaga_utils::*;
/// A gralloc implementation capable of allocation `VkDeviceMemory`.
pub struct VulkanoGralloc {
devices: Map<PhysicalDeviceType, Arc<Device>>,
device_physical_index: Map<PhysicalDeviceType, usize>,
device_by_id: Map<DeviceId, Arc<Device>>,
has_integrated_gpu: bool,
}
@ -91,6 +91,21 @@ unsafe impl MappedRegion for VulkanoMapping {
}
}
trait DeviceExt {
/// Get a unique identifier for the device.
fn get_id(&self) -> DeviceId;
}
impl DeviceExt for Device {
fn get_id(&self) -> DeviceId {
let properties = self.physical_device().properties;
DeviceId {
device_uuid: properties.device_uuid.expect("Vulkan should support uuid"),
driver_uuid: properties.driver_uuid.expect("Vulkan should support uuid"),
}
}
}
impl VulkanoGralloc {
/// Returns a new `VulkanGralloc' instance upon success.
pub fn init() -> RutabagaResult<Box<dyn Gralloc>> {
@ -113,10 +128,10 @@ impl VulkanoGralloc {
)?;
let mut devices: Map<PhysicalDeviceType, Arc<Device>> = Default::default();
let mut device_physical_index: Map<PhysicalDeviceType, usize> = Default::default();
let mut device_by_id: Map<DeviceId, Arc<Device>> = Default::default();
let mut has_integrated_gpu = false;
for (physical_index, physical) in instance.enumerate_physical_devices()?.enumerate() {
for physical in instance.enumerate_physical_devices()? {
let queue_family_index = physical
.queue_family_properties()
.iter()
@ -154,8 +169,8 @@ impl VulkanoGralloc {
// If we have two devices of the same type (two integrated GPUs), the old value is
// dropped. Vulkano is verbose enough such that a keener selection algorithm may
// be used, but the need for such complexity does not seem to exist now.
devices.insert(device_type, device);
device_physical_index.insert(device_type, physical_index);
devices.insert(device_type, device.clone());
device_by_id.insert(device.get_id(), device);
};
}
@ -167,7 +182,7 @@ impl VulkanoGralloc {
Ok(Box::new(VulkanoGralloc {
devices,
device_physical_index,
device_by_id,
has_integrated_gpu,
}))
}
@ -274,10 +289,6 @@ impl Gralloc for VulkanoGralloc {
&PhysicalDeviceType::DiscreteGpu
};
let physical_index = *self
.device_physical_index
.get(device_type)
.ok_or(RutabagaError::InvalidGrallocGpuType)?;
let device = self
.devices
.get(device_type)
@ -360,7 +371,7 @@ impl Gralloc for VulkanoGralloc {
reqs.vulkan_info = Some(VulkanInfo {
memory_idx: memory_type_index as u32,
physical_device_idx: physical_index as u32,
device_id: device.get_id(),
});
Ok(reqs)
@ -448,16 +459,9 @@ impl Gralloc for VulkanoGralloc {
vulkan_info: VulkanInfo,
size: u64,
) -> RutabagaResult<Box<dyn MappedRegion>> {
let device_type = self
.device_physical_index
.iter()
.find(|entry| *entry.1 == vulkan_info.physical_device_idx as usize)
.ok_or(RutabagaError::InvalidVulkanInfo)?
.0;
let device = self
.devices
.get(device_type)
.device_by_id
.get(&vulkan_info.device_id)
.ok_or(RutabagaError::InvalidVulkanInfo)?;
let device_memory = unsafe {

View file

@ -97,11 +97,20 @@ pub struct Resource3DInfo {
pub modifier: u64,
}
/// Memory index and physical device index of the associated VkDeviceMemory.
/// A unique identifier for a device.
#[derive(
Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize,
)]
pub struct DeviceId {
pub device_uuid: [u8; 16],
pub driver_uuid: [u8; 16],
}
/// Memory index and physical device id of the associated VkDeviceMemory.
#[derive(Copy, Clone, Default)]
pub struct VulkanInfo {
pub memory_idx: u32,
pub physical_device_idx: u32,
pub device_id: DeviceId,
}
/// Rutabaga context init capset id mask.

View file

@ -69,6 +69,7 @@ use libc::ERANGE;
use remain::sorted;
use resources::Alloc;
use resources::SystemAllocator;
use rutabaga_gfx::DeviceId;
use rutabaga_gfx::RutabagaGralloc;
use rutabaga_gfx::RutabagaHandle;
use rutabaga_gfx::VulkanInfo;
@ -281,7 +282,7 @@ pub enum VmMemorySource {
descriptor: SafeDescriptor,
handle_type: u32,
memory_idx: u32,
physical_device_idx: u32,
device_id: DeviceId,
size: u64,
},
/// Register the current rutabaga external mapping.
@ -313,7 +314,7 @@ impl VmMemorySource {
descriptor,
handle_type,
memory_idx,
physical_device_idx,
device_id,
size,
} => {
let mapped_region = match gralloc.import_and_map(
@ -323,7 +324,7 @@ impl VmMemorySource {
},
VulkanInfo {
memory_idx,
physical_device_idx,
device_id,
},
size,
) {