Files
clan-core/pkgs/rutabaga-gfx-ffi/0003-rutabaga_gfx-fix-stale-cross-domain-keymap-resources.patch
2023-12-15 12:12:46 +01:00

205 lines
9.3 KiB
Diff

From 37d51bb5bcf329bd098a0365dcbfbafc2222fddf Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=B6rg=20Thalheim?= <joerg@thalheim.io>
Date: Thu, 14 Dec 2023 14:54:51 +0100
Subject: [PATCH 3/3] rutabaga_gfx: fix stale cross-domain keymap resources
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
when running vulkaninfo and other apps it seems that this resource
is requested multiple times and it fails after the first time.
After this patch vulkaninfo no longer produces any qemu errors.
Signed-off-by: Jörg Thalheim <joerg@thalheim.io>
---
rutabaga_gfx/src/cross_domain/mod.rs | 155 ++++++++++++---------------
1 file changed, 68 insertions(+), 87 deletions(-)
diff --git a/rutabaga_gfx/src/cross_domain/mod.rs b/rutabaga_gfx/src/cross_domain/mod.rs
index 6eb7ec988..34b51d4da 100644
--- a/rutabaga_gfx/src/cross_domain/mod.rs
+++ b/rutabaga_gfx/src/cross_domain/mod.rs
@@ -69,7 +69,7 @@ pub enum CrossDomainToken {
pub(crate) enum CrossDomainItem {
ImageRequirements(ImageMemoryRequirements),
- WaylandKeymap(SafeDescriptor),
+ WaylandKeymap(Arc<RutabagaHandle>),
#[allow(dead_code)] // `WaylandReadPipe` is never constructed on Windows.
WaylandReadPipe(File),
WaylandWritePipe(File),
@@ -340,7 +340,10 @@ fn handle_fence(
*identifier = match *identifier_type {
CROSS_DOMAIN_ID_TYPE_VIRTGPU_BLOB => add_item(
&self.item_state,
- CrossDomainItem::WaylandKeymap(file.into()),
+ CrossDomainItem::WaylandKeymap(Arc::new(RutabagaHandle {
+ os_handle: file.into(),
+ handle_type: RUTABAGA_MEM_HANDLE_TYPE_SHM,
+ })),
),
CROSS_DOMAIN_ID_TYPE_WRITE_PIPE => add_item(
&self.item_state,
@@ -670,95 +673,73 @@ fn context_create_blob(
) -> RutabagaResult<RutabagaResource> {
let item_id = resource_create_blob.blob_id as u32;
- // We don't want to remove requirements blobs, since they can be used for subsequent
- // allocations. We do want to remove Wayland keymaps, since they are mapped the guest
- // and then never used again. The current protocol encodes this as divisiblity by 2.
- if item_id % 2 == 0 {
- let items = self.item_state.lock().unwrap();
- let item = items
- .table
- .get(&item_id)
- .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
-
- match item {
- CrossDomainItem::ImageRequirements(reqs) => {
- if reqs.size != resource_create_blob.size {
- return Err(RutabagaError::SpecViolation("blob size mismatch"));
- }
-
- // Strictly speaking, it's against the virtio-gpu spec to allocate memory in the context
- // create blob function, which says "the actual allocation is done via
- // VIRTIO_GPU_CMD_SUBMIT_3D." However, atomic resource creation is easiest for the
- // cross-domain use case, so whatever.
- let hnd = match handle_opt {
- Some(handle) => handle,
- None => self.gralloc.lock().unwrap().allocate_memory(*reqs)?,
- };
-
- let info_3d = Resource3DInfo {
- width: reqs.info.width,
- height: reqs.info.height,
- drm_fourcc: reqs.info.drm_format.into(),
- strides: reqs.strides,
- offsets: reqs.offsets,
- modifier: reqs.modifier,
- guest_cpu_mappable: (resource_create_blob.blob_flags
- & RUTABAGA_BLOB_FLAG_USE_MAPPABLE)
- != 0,
- };
+ let items = self.item_state.lock().unwrap();
+ let item = items
+ .table
+ .get(&item_id)
+ .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
- Ok(RutabagaResource {
- resource_id,
- handle: Some(Arc::new(hnd)),
- blob: true,
- blob_mem: resource_create_blob.blob_mem,
- blob_flags: resource_create_blob.blob_flags,
- map_info: Some(reqs.map_info | RUTABAGA_MAP_ACCESS_RW),
- info_2d: None,
- info_3d: Some(info_3d),
- vulkan_info: reqs.vulkan_info,
- backing_iovecs: None,
- component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
- size: resource_create_blob.size,
- mapping: None,
- })
- }
- _ => Err(RutabagaError::InvalidCrossDomainItemType),
+ match item {
+ CrossDomainItem::WaylandKeymap(handle) => {
+ Ok(RutabagaResource {
+ resource_id,
+ handle: Some(Arc::clone(handle)),
+ blob: true,
+ blob_mem: resource_create_blob.blob_mem,
+ blob_flags: resource_create_blob.blob_flags,
+ map_info: Some(RUTABAGA_MAP_CACHE_CACHED | RUTABAGA_MAP_ACCESS_READ),
+ info_2d: None,
+ info_3d: None,
+ vulkan_info: None,
+ backing_iovecs: None,
+ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
+ size: resource_create_blob.size,
+ mapping: None,
+ })
}
- } else {
- let item = self
- .item_state
- .lock()
- .unwrap()
- .table
- .remove(&item_id)
- .ok_or(RutabagaError::InvalidCrossDomainItemId)?;
-
- match item {
- CrossDomainItem::WaylandKeymap(descriptor) => {
- let hnd = RutabagaHandle {
- os_handle: descriptor,
- handle_type: RUTABAGA_MEM_HANDLE_TYPE_SHM,
- };
-
- Ok(RutabagaResource {
- resource_id,
- handle: Some(Arc::new(hnd)),
- blob: true,
- blob_mem: resource_create_blob.blob_mem,
- blob_flags: resource_create_blob.blob_flags,
- map_info: Some(RUTABAGA_MAP_CACHE_CACHED | RUTABAGA_MAP_ACCESS_READ),
- info_2d: None,
- info_3d: None,
- vulkan_info: None,
- backing_iovecs: None,
- component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
- size: resource_create_blob.size,
- mapping: None,
- })
+ CrossDomainItem::ImageRequirements(reqs) => {
+ if reqs.size != resource_create_blob.size {
+ return Err(RutabagaError::SpecViolation("blob size mismatch"));
}
- _ => Err(RutabagaError::InvalidCrossDomainItemType),
+
+ // Strictly speaking, it's against the virtio-gpu spec to allocate memory in the context
+ // create blob function, which says "the actual allocation is done via
+ // VIRTIO_GPU_CMD_SUBMIT_3D." However, atomic resource creation is easiest for the
+ // cross-domain use case, so whatever.
+ let hnd = match handle_opt {
+ Some(handle) => handle,
+ None => self.gralloc.lock().unwrap().allocate_memory(*reqs)?,
+ };
+
+ let info_3d = Resource3DInfo {
+ width: reqs.info.width,
+ height: reqs.info.height,
+ drm_fourcc: reqs.info.drm_format.into(),
+ strides: reqs.strides,
+ offsets: reqs.offsets,
+ modifier: reqs.modifier,
+ guest_cpu_mappable: (resource_create_blob.blob_flags
+ & RUTABAGA_BLOB_FLAG_USE_MAPPABLE)
+ != 0,
+ };
+
+ Ok(RutabagaResource {
+ resource_id,
+ handle: Some(Arc::new(hnd)),
+ blob: true,
+ blob_mem: resource_create_blob.blob_mem,
+ blob_flags: resource_create_blob.blob_flags,
+ map_info: Some(reqs.map_info | RUTABAGA_MAP_ACCESS_RW),
+ info_2d: None,
+ info_3d: Some(info_3d),
+ vulkan_info: reqs.vulkan_info,
+ backing_iovecs: None,
+ component_mask: 1 << (RutabagaComponentType::CrossDomain as u8),
+ size: resource_create_blob.size,
+ mapping: None,
+ })
}
+ id => Err(RutabagaError::InvalidCrossDomainItemType),
}
}
--
2.42.0