rutabaga_gfx: enable per-context/per-ring fencing for virgl_renderer

Permits virglrenderer contexts to make use of per-context/per-ring
fencing.

BUG=b:193892617
TEST=Run glxgears and vkcube in a crosvm guest VM.

Change-Id: I9800d3fbab788602a25f2a118619910300126d4b
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3453115
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Ryan Neph <ryanneph@google.com>
This commit is contained in:
Ryan Neph 2022-02-10 14:09:51 -08:00 committed by Chromeos LUCI
parent 7df6c2ee05
commit 8452832b97
2 changed files with 47 additions and 1 deletions

View file

@ -187,7 +187,7 @@ pub trait RutabagaContext {
fn detach(&mut self, _resource: &RutabagaResource); fn detach(&mut self, _resource: &RutabagaResource);
/// Implementations must create a fence on specified `ring_idx` in `fence`. This /// Implementations must create a fence on specified `ring_idx` in `fence`. This
/// allows for multiple syncrhonizations timelines per RutabagaContext. /// allows for multiple synchronizations timelines per RutabagaContext.
fn context_create_fence(&mut self, _fence: RutabagaFence) -> RutabagaResult<()> { fn context_create_fence(&mut self, _fence: RutabagaFence) -> RutabagaResult<()> {
Err(RutabagaError::Unsupported) Err(RutabagaError::Unsupported)
} }

View file

@ -12,6 +12,8 @@ use std::convert::TryFrom;
use std::mem::{size_of, transmute}; use std::mem::{size_of, transmute};
use std::os::raw::{c_char, c_void}; use std::os::raw::{c_char, c_void};
use std::os::unix::io::AsRawFd; use std::os::unix::io::AsRawFd;
use std::panic::catch_unwind;
use std::process::abort;
use std::ptr::null_mut; use std::ptr::null_mut;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
@ -75,6 +77,18 @@ impl RutabagaContext for VirglRendererContext {
fn component_type(&self) -> RutabagaComponentType { fn component_type(&self) -> RutabagaComponentType {
RutabagaComponentType::VirglRenderer RutabagaComponentType::VirglRenderer
} }
fn context_create_fence(&mut self, fence: RutabagaFence) -> RutabagaResult<()> {
let ret = unsafe {
virgl_renderer_context_create_fence(
fence.ctx_id,
fence.flags,
fence.ring_idx as u64,
fence.fence_id as *mut ::std::os::raw::c_void,
)
};
ret_to_res(ret)
}
} }
impl Drop for VirglRendererContext { impl Drop for VirglRendererContext {
@ -113,6 +127,35 @@ extern "C" fn debug_callback(fmt: *const ::std::os::raw::c_char, ap: stdio::va_l
} }
} }
/// Virglrenderer's vtest renderer currently expects an opaque "void *fence_cookie" rather than a
/// bare "u64 fence_id", so we cannot use the common implementation from renderer_utils yet.
///
/// TODO(ryanneph): re-evaluate if vtest can be modified so this can be unified with
/// write_context_fence() from renderer_utils before promoting to cfg(feature = "virgl_renderer").
#[cfg(feature = "virgl_renderer_next")]
extern "C" fn write_context_fence(
cookie: *mut c_void,
ctx_id: u32,
ring_idx: u64,
fence_cookie: *mut c_void,
) {
catch_unwind(|| {
assert!(!cookie.is_null());
let cookie = unsafe { &*(cookie as *mut VirglCookie) };
// Call fence completion callback
if let Some(handler) = &cookie.fence_handler {
handler.call(RutabagaFence {
flags: RUTABAGA_FLAG_FENCE | RUTABAGA_FLAG_INFO_RING_IDX,
fence_id: fence_cookie as u64,
ctx_id,
ring_idx: ring_idx as u8,
});
}
})
.unwrap_or_else(|_| abort())
}
const VIRGL_RENDERER_CALLBACKS: &virgl_renderer_callbacks = &virgl_renderer_callbacks { const VIRGL_RENDERER_CALLBACKS: &virgl_renderer_callbacks = &virgl_renderer_callbacks {
#[cfg(not(feature = "virgl_renderer_next"))] #[cfg(not(feature = "virgl_renderer_next"))]
version: 1, version: 1,
@ -123,7 +166,10 @@ const VIRGL_RENDERER_CALLBACKS: &virgl_renderer_callbacks = &virgl_renderer_call
destroy_gl_context: None, destroy_gl_context: None,
make_current: None, make_current: None,
get_drm_fd: None, get_drm_fd: None,
#[cfg(not(feature = "virgl_renderer_next"))]
write_context_fence: None, write_context_fence: None,
#[cfg(feature = "virgl_renderer_next")]
write_context_fence: Some(write_context_fence),
#[cfg(not(feature = "virgl_renderer_next"))] #[cfg(not(feature = "virgl_renderer_next"))]
get_server_fd: None, get_server_fd: None,
#[cfg(feature = "virgl_renderer_next")] #[cfg(feature = "virgl_renderer_next")]