Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion coverage_config_x86_64.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"coverage_score": 83.51,
"coverage_score": 83.00,
"exclude_path": "xtask",
"crate_features": ""
}
1 change: 1 addition & 0 deletions vhost-device-gpu/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

### Added

- [[#988]] (https://github.com/rust-vmm/vhost-device/pull/988) vhost-device-gpu: Add blob resource support and Venus capset for virglrenderer backend
- [[#945]] (https://github.com/rust-vmm/vhost-device/pull/945) Implement RESOURCE_ASSIGN_UUID command
- [[#932]] (https://github.com/rust-vmm/vhost-device/pull/932) vhost-device-gpu: Add support for GPU device path
- [[#927]] (https://github.com/rust-vmm/vhost-device/pull/927) vhost-device-gpu: Introduce headless mode
Expand Down
2 changes: 1 addition & 1 deletion vhost-device-gpu/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ log = "0.4"
[target.'cfg(not(target_env = "musl"))'.dependencies]
rutabaga_gfx = "0.1.75"
thiserror = "2.0.18"
virglrenderer = { version = "0.1.4", optional = true }
virglrenderer = { version = "0.1.6", optional = true }
vhost = { workspace = true }
vhost-user-backend = { workspace = true }
virtio-bindings = { workspace = true }
Expand Down
17 changes: 5 additions & 12 deletions vhost-device-gpu/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ A virtio-gpu device using the vhost-user protocol.
Possible values:
- virgl: [virglrenderer] OpenGL implementation, superseded by Virgl2
- virgl2: [virglrenderer] OpenGL implementation
- venus: [virglrenderer] Vulkan implementation with hardware acceleration
- gfxstream-vulkan: [gfxstream] Vulkan implementation (partial support only)
NOTE: Can only be used for 2D display output for now, there is no hardware acceleration yet
- gfxstream-gles: [gfxstream] OpenGL ES implementation (partial support only)
Expand Down Expand Up @@ -82,21 +83,13 @@ with GNU libc, so the CI is setup to not build this device for musl targets.
It might be possible to build those libraries using musl and then build the gpu
device, but this is not tested.

We are currently only supporting sharing the display output to QEMU through a
socket using the transfer_read operation triggered by
`VIRTIO_GPU_CMD_TRANSFER_FROM_HOST_3D` to transfer data from and to virtio-gpu 3D
resources. It'll be nice to have support for directly sharing display output
resource using dmabuf.

This device does not yet support the `VIRTIO_GPU_CMD_RESOURCE_CREATE_BLOB`,
`VIRTIO_GPU_CMD_SET_SCANOUT_BLOB` and `VIRTIO_GPU_CMD_RESOURCE_ASSIGN_UUID` features.
This requires https://github.com/rust-vmm/vhost/pull/251, which in turn requires QEMU API stabilization.
Because blob resources are not yet supported, some capsets are limited:
- Venus (Vulkan implementation in virglrenderer project) support is not available at all.
- gfxstream-vulkan and gfxstream-gles support are exposed, but can practically only be used for display output, there is no hardware acceleration yet.
This device does not yet support the `VIRTIO_GPU_CMD_SET_SCANOUT_BLOB` feature.
Regular SET_SCANOUT handles both 2D and blob resources.

## Features

This crate supports three GPU backends: virglrenderer, gfxstream (both enabled by default), and null.
Blob resource support enables Venus (Vulkan) for hardware-accelerated Vulkan rendering.

The **virglrenderer** backend uses the [virglrenderer-rs](https://crates.io/crates/virglrenderer-rs)
crate, which provides Rust bindings to the native virglrenderer library. It translates
Expand Down
73 changes: 69 additions & 4 deletions vhost-device-gpu/src/backend/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,89 @@
//
Comment thread
aesteve-rh marked this conversation as resolved.
// SPDX-License-Identifier: Apache-2.0 or BSD-3-Clause

use std::sync::{Arc, Mutex};
use std::{
os::fd::{AsFd, AsRawFd},
sync::{Arc, Mutex},
};

use log::{debug, error};
use log::{debug, error, trace};
use vhost::vhost_user::{
gpu_message::{VhostUserGpuCursorPos, VhostUserGpuCursorUpdate, VhostUserGpuEdidRequest},
GpuBackend,
message::{VhostUserMMap, VhostUserMMapFlags},
Backend, GpuBackend, VhostUserFrontendReqHandler,
};
use vm_memory::VolatileSlice;

use crate::{
gpu_types::{FenceDescriptor, FenceState, Transfer3DDesc, VirtioGpuRing},
protocol::{
GpuResponse::{self, ErrUnspec, OkDisplayInfo, OkEdid, OkNoData},
GpuResponse::{self, ErrInvalidParameter, ErrUnspec, OkDisplayInfo, OkEdid, OkNoData},
VirtioGpuResult, EDID_BLOB_MAX_SIZE, VIRTIO_GPU_MAX_SCANOUTS,
},
renderer::Renderer,
};

/// Shared memory region ID for host-visible memory (blob resources)
const VIRTIO_GPU_SHM_ID_HOST_VISIBLE: u8 = 1;

/// Common helper for mapping blob resources.
/// Maps a blob resource using the vhost-user backend's shmem_map.
pub fn common_map_blob(
backend: &Backend,
flags: VhostUserMMapFlags,
handle_fd: &(impl AsFd + AsRawFd),
blob_size: u64,
offset: u64,
resource_id: u32,
) -> Result<(), GpuResponse> {
trace!("Mapping blob resource_id={resource_id} offset={offset} size={blob_size}");

if blob_size > usize::MAX as u64 {
error!("Blob size {blob_size} exceeds platform limits for resource_id={resource_id}");
return Err(ErrInvalidParameter);
}

let map_request = VhostUserMMap {
shmid: VIRTIO_GPU_SHM_ID_HOST_VISIBLE,
padding: Default::default(),
fd_offset: 0,
shm_offset: offset,
len: blob_size,
flags: flags.bits(),
};

backend.shmem_map(&map_request, handle_fd).map_err(|e| {
error!("Failed to mmap by frontend: {e:?}");
ErrUnspec
})?;

Ok(())
}

/// Common helper for unmapping blob resources.
/// Unmaps a blob resource using the vhost-user backend's shmem_unmap.
pub fn common_unmap_blob(
backend: &Backend,
blob_size: u64,
offset: u64,
) -> Result<(), GpuResponse> {
let unmap_request = VhostUserMMap {
shmid: VIRTIO_GPU_SHM_ID_HOST_VISIBLE,
padding: Default::default(),
fd_offset: 0,
shm_offset: offset,
len: blob_size,
flags: 0,
};

backend.shmem_unmap(&unmap_request).map_err(|e| {
error!("Failed to unmap by frontend: {e:?}");
ErrUnspec
})?;

Ok(())
}

#[derive(Debug, Clone)]
pub struct VirtioGpuScanout {
pub resource_id: u32,
Expand Down
Loading