1
0
Fork 0
forked from wry/wry

allocator: don't require render usage for bridged buffers

This commit is contained in:
Julian Orth 2024-09-05 11:48:30 +02:00
parent 1bacaa7b02
commit bf65da4c76
15 changed files with 152 additions and 54 deletions

View file

@ -12,8 +12,8 @@ use {
edid::Descriptor,
format::{Format, ARGB8888, XRGB8888},
gfx_api::{
AcquireSync, BufferResv, GfxApiOpt, GfxContext, GfxFramebuffer, GfxRenderPass,
GfxTexture, ReleaseSync, SyncFile,
needs_render_usage, AcquireSync, BufferResv, GfxApiOpt, GfxContext, GfxFramebuffer,
GfxRenderPass, GfxTexture, ReleaseSync, SyncFile,
},
ifs::{
wl_output::OutputId,
@ -46,7 +46,7 @@ use {
ahash::{AHashMap, AHashSet},
arrayvec::ArrayVec,
bstr::{BString, ByteSlice},
indexmap::{indexset, IndexSet},
indexmap::{indexset, IndexMap, IndexSet},
isnt::std_1::collections::IsntHashMap2Ext,
jay_config::video::GfxApi,
once_cell::sync::Lazy,
@ -2853,18 +2853,24 @@ impl MetalBackend {
None => return Err(MetalError::MissingDevFormat(format.name)),
Some(f) => f,
};
let possible_modifiers: Vec<_> = dev_gfx_format
let possible_modifiers: IndexMap<_, _> = dev_gfx_format
.write_modifiers
.iter()
.filter(|m| plane_modifiers.contains(*m))
.copied()
.filter(|(m, _)| plane_modifiers.contains(*m))
.map(|(m, v)| (*m, v))
.collect();
if possible_modifiers.is_empty() {
log::warn!("Scanout modifiers: {:?}", plane_modifiers);
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.write_modifiers);
log::warn!(
"DEV GFX modifiers: {:?}",
dev_gfx_format.write_modifiers.keys()
);
return Err(MetalError::MissingDevModifier(format.name));
}
let mut usage = GBM_BO_USE_RENDERING | GBM_BO_USE_SCANOUT;
if !needs_render_usage(possible_modifiers.values().copied()) {
usage &= !GBM_BO_USE_RENDERING;
}
if cursor {
usage |= GBM_BO_USE_LINEAR;
};
@ -2873,7 +2879,7 @@ impl MetalBackend {
width,
height,
format,
&possible_modifiers,
possible_modifiers.keys(),
usage,
);
let dev_bo = match dev_bo {
@ -2906,27 +2912,30 @@ impl MetalBackend {
None => return Err(MetalError::MissingRenderFormat(format.name)),
Some(f) => f,
};
let possible_modifiers: Vec<_> = render_gfx_format
let possible_modifiers: IndexMap<_, _> = render_gfx_format
.write_modifiers
.iter()
.filter(|m| dev_gfx_format.read_modifiers.contains(*m))
.copied()
.filter(|(m, _)| dev_gfx_format.read_modifiers.contains(*m))
.map(|(m, v)| (*m, v))
.collect();
if possible_modifiers.is_empty() {
log::warn!(
"Render GFX modifiers: {:?}",
render_gfx_format.write_modifiers
render_gfx_format.write_modifiers.keys()
);
log::warn!("DEV GFX modifiers: {:?}", dev_gfx_format.read_modifiers);
return Err(MetalError::MissingRenderModifier(format.name));
}
usage = GBM_BO_USE_RENDERING | GBM_BO_USE_LINEAR;
if !needs_render_usage(possible_modifiers.values().copied()) {
usage &= !GBM_BO_USE_RENDERING;
}
let render_bo = render_ctx.gbm.create_bo(
&self.state.dma_buf_ids,
width,
height,
format,
&possible_modifiers,
possible_modifiers.keys(),
usage,
);
let render_bo = match render_bo {

View file

@ -389,7 +389,7 @@ impl XBackend {
width,
height,
XRGB8888,
&format.write_modifiers,
format.write_modifiers.keys(),
GBM_BO_USE_RENDERING,
)?;
let dma = bo.dmabuf();

View file

@ -15,7 +15,7 @@ use {
video::{dmabuf::DmaBuf, drm::sync_obj::SyncObjCtx, Modifier},
},
ahash::AHashMap,
indexmap::IndexSet,
indexmap::{IndexMap, IndexSet},
jay_config::video::{GfxApi, Transform},
std::{
any::Any,
@ -570,11 +570,20 @@ pub trait GfxContext: Debug {
fn sync_obj_ctx(&self) -> Option<&Rc<SyncObjCtx>>;
}
#[derive(Clone, Debug)]
pub struct GfxWriteModifier {
pub needs_render_usage: bool,
}
pub fn needs_render_usage<'a>(mut modifiers: impl Iterator<Item = &'a GfxWriteModifier>) -> bool {
modifiers.any(|m| m.needs_render_usage)
}
#[derive(Debug)]
pub struct GfxFormat {
pub format: &'static Format,
pub read_modifiers: IndexSet<Modifier>,
pub write_modifiers: IndexSet<Modifier>,
pub write_modifiers: IndexMap<Modifier, GfxWriteModifier>,
}
#[derive(Error)]
@ -594,13 +603,15 @@ impl GfxFormat {
format: self.format,
read_modifiers: self
.read_modifiers
.intersection(&other.write_modifiers)
.iter()
.copied()
.filter(|m| other.write_modifiers.contains_key(m))
.collect(),
write_modifiers: self
.write_modifiers
.intersection(&other.read_modifiers)
.copied()
.iter()
.map(|(m, v)| (*m, v.clone()))
.filter(|(m, _)| other.read_modifiers.contains(m))
.collect(),
}
}

View file

@ -1,7 +1,7 @@
use {
crate::{
format::{formats, Format},
gfx_api::GfxFormat,
gfx_api::{GfxFormat, GfxWriteModifier},
gfx_apis::gl::{
egl::{
context::EglContext,
@ -173,13 +173,18 @@ impl EglDisplay {
continue;
}
let mut read_modifiers = IndexSet::new();
let mut write_modifiers = IndexSet::new();
let mut write_modifiers = IndexMap::new();
for modifier in format.modifiers.values() {
if modifier.external_only && !supports_external_only {
continue;
}
if !modifier.external_only {
write_modifiers.insert(modifier.modifier);
write_modifiers.insert(
modifier.modifier,
GfxWriteModifier {
needs_render_usage: true,
},
);
}
read_modifiers.insert(modifier.modifier);
}

View file

@ -4,7 +4,7 @@ use {
format::{Format, XRGB8888},
gfx_api::{
AcquireSync, BufferResv, BufferResvUser, GfxApiOpt, GfxFormat, GfxFramebuffer,
GfxTexture, ReleaseSync, SyncFile,
GfxTexture, GfxWriteModifier, ReleaseSync, SyncFile,
},
gfx_apis::vulkan::{
allocator::VulkanAllocator,
@ -158,7 +158,14 @@ impl VulkanDevice {
.modifiers
.values()
.filter(|m| m.render_limits.is_some())
.map(|m| m.modifier)
.map(|m| {
(
m.modifier,
GfxWriteModifier {
needs_render_usage: !m.render_needs_bridge,
},
)
})
.collect(),
},
)

View file

@ -70,7 +70,7 @@ impl Global for JayCompositorGlobal {
}
fn version(&self) -> u32 {
8
9
}
fn required_caps(&self) -> ClientCaps {

View file

@ -12,6 +12,7 @@ use {
};
pub const FORMATS_SINCE: Version = Version(7);
pub const WRITE_MODIFIER_2_SINCE: Version = Version(9);
pub struct JayRenderCtx {
pub id: JayRenderCtxId,
@ -30,13 +31,22 @@ impl JayRenderCtx {
self_id: self.id,
format: format.format.drm,
});
for modifier in &format.write_modifiers {
for (modifier, gwm) in &format.write_modifiers {
if self.version >= WRITE_MODIFIER_2_SINCE {
self.client.event(WriteModifier2 {
self_id: self.id,
format: format.format.drm,
modifier: *modifier,
needs_render_usage: gwm.needs_render_usage as _,
});
} else {
self.client.event(WriteModifier {
self_id: self.id,
format: format.format.drm,
modifier: *modifier,
});
}
}
for modifier in &format.read_modifiers {
self.client.event(ReadModifier {
self_id: self.id,

View file

@ -414,10 +414,10 @@ impl JayScreencast {
}
let mut usage = BO_USE_RENDERING;
let modifiers = match self.linear.get() {
true if format.write_modifiers.contains(&LINEAR_MODIFIER) => {
true if format.write_modifiers.contains_key(&LINEAR_MODIFIER) => {
vec![LINEAR_MODIFIER]
}
true if format.write_modifiers.contains(&INVALID_MODIFIER) => {
true if format.write_modifiers.contains_key(&INVALID_MODIFIER) => {
usage |= BO_USE_LINEAR;
vec![INVALID_MODIFIER]
}
@ -425,7 +425,7 @@ impl JayScreencast {
false if format.write_modifiers.is_empty() => {
return Err(JayScreencastError::XRGB8888Writing)
}
false => format.write_modifiers.iter().copied().collect(),
false => format.write_modifiers.keys().copied().collect(),
};
let buffer = ctx.allocator().create_bo(
&self.client.state.dma_buf_ids,

View file

@ -4,7 +4,7 @@ use {
format::{Format, ARGB8888, XRGB8888},
gfx_api::{
CopyTexture, FillRect, FramebufferRect, GfxApiOpt, GfxContext, GfxError, GfxFormat,
GfxFramebuffer, GfxImage, GfxTexture, ResetStatus, SyncFile,
GfxFramebuffer, GfxImage, GfxTexture, GfxWriteModifier, ResetStatus, SyncFile,
},
rect::Rect,
theme::Color,
@ -55,7 +55,18 @@ impl TestGfxCtx {
GfxFormat {
format: f,
read_modifiers: modifiers.clone(),
write_modifiers: modifiers.clone(),
write_modifiers: modifiers
.iter()
.copied()
.map(|m| {
(
m,
GfxWriteModifier {
needs_render_usage: false,
},
)
})
.collect(),
},
);
}

View file

@ -323,7 +323,7 @@ fn finish_display_connect(dpy: Rc<PortalDisplayPrelude>) {
con: dpy.con.clone(),
owner: Default::default(),
caps: Default::default(),
version: Version(version.min(7)),
version: Version(version.min(9)),
});
dpy.con.add_object(jc.clone());
dpy.registry.request_bind(name, jc.version.0, jc.deref());

View file

@ -2,7 +2,7 @@ mod screencast_gui;
use {
crate::{
allocator::{AllocatorError, BufferObject, BO_USE_RENDERING},
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
dbus::{prelude::Variant, DbusObject, DictEntry, DynamicType, PendingReply},
format::{Format, XRGB8888},
ifs::jay_screencast::CLIENT_BUFFERS_SINCE,
@ -204,7 +204,7 @@ impl PwClientNodeOwner for StartingScreencast {
}
let ptl_format = PwClientNodePortSupportedFormat {
format: format.format,
modifiers: format.write_modifiers.iter().copied().collect(),
modifiers: format.write_modifiers.keys().copied().collect(),
};
supported_formats.formats.push(ptl_format);
}
@ -380,13 +380,28 @@ impl StartedScreencast {
let Some(ctx) = self.dpy.render_ctx.get() else {
return Err(BufferAllocationError::NoRenderContext);
};
let mut usage = BO_USE_RENDERING;
if let Some(sf) = &ctx.server_formats {
if let Some(format) = sf.get(&format.drm) {
let no_render_usage = modifiers.iter().all(|m| {
format
.write_modifiers
.get(m)
.map(|w| !w.needs_render_usage)
.unwrap_or(false)
});
if no_render_usage {
usage = BufferUsage::none();
}
}
}
let buffer = ctx.ctx.ctx.allocator().create_bo(
&self.dpy.state.dma_buf_ids,
width,
height,
format,
modifiers,
BO_USE_RENDERING,
usage,
)?;
Ok(buffer)
}

View file

@ -1,11 +1,11 @@
use {
crate::{
allocator::{BufferObject, BO_USE_RENDERING},
allocator::{BufferObject, BufferUsage, BO_USE_RENDERING},
async_engine::{Phase, SpawnedFuture},
cursor::KnownCursor,
fixed::Fixed,
format::ARGB8888,
gfx_api::{AcquireSync, GfxContext, GfxFramebuffer, ReleaseSync},
gfx_api::{needs_render_usage, AcquireSync, GfxContext, GfxFramebuffer, ReleaseSync},
ifs::zwlr_layer_shell_v1::OVERLAY,
portal::ptl_display::{PortalDisplay, PortalOutput, PortalSeat},
renderer::renderer_base::RendererBase,
@ -723,7 +723,11 @@ impl WindowData {
log::error!("Render context cannot render to ARGB8888 format");
return;
}
let modifiers: Vec<_> = format.write_modifiers.iter().copied().collect();
let modifiers: Vec<_> = format.write_modifiers.keys().copied().collect();
let mut usage = BO_USE_RENDERING;
if !needs_render_usage(format.write_modifiers.values()) {
usage = BufferUsage::none();
}
for _ in 0..NUM_BUFFERS {
let bo = match ctx.ctx.ctx.allocator().create_bo(
&self.dpy.state.dma_buf_ids,
@ -731,7 +735,7 @@ impl WindowData {
height,
ARGB8888,
&modifiers,
BO_USE_RENDERING,
usage,
) {
Ok(b) => b,
Err(e) => {

View file

@ -1,12 +1,13 @@
use {
crate::{
allocator::{AllocatorError, BufferObject, BO_USE_RENDERING},
allocator::{AllocatorError, BufferObject, BufferUsage, BO_USE_RENDERING},
format::XRGB8888,
gfx_api::GfxError,
gfx_api::{needs_render_usage, GfxError},
scale::Scale,
state::State,
video::drm::DrmError,
},
indexmap::IndexMap,
jay_config::video::Transform,
std::{ops::Deref, rc::Rc},
thiserror::Error,
@ -49,17 +50,22 @@ pub fn take_screenshot(
return Err(ScreenshooterError::EmptyDisplay);
}
let formats = ctx.formats();
let modifiers: Vec<_> = match formats.get(&XRGB8888.drm) {
let modifiers: IndexMap<_, _> = match formats.get(&XRGB8888.drm) {
None => return Err(ScreenshooterError::XRGB8888),
Some(f) => f
.write_modifiers
.intersection(&f.read_modifiers)
.copied()
.iter()
.filter(|(m, _)| f.read_modifiers.contains(*m))
.collect(),
};
if modifiers.is_empty() {
return Err(ScreenshooterError::Modifiers);
}
let mut usage = BO_USE_RENDERING;
if !needs_render_usage(modifiers.values().copied()) {
usage = BufferUsage::none();
}
let modifiers: Vec<_> = modifiers.keys().copied().copied().collect();
let allocator = ctx.allocator();
let bo = allocator.create_bo(
&state.dma_buf_ids,
@ -67,7 +73,7 @@ pub fn take_screenshot(
extents.height(),
XRGB8888,
&modifiers,
BO_USE_RENDERING,
usage,
)?;
let fb = ctx.clone().dmabuf_fb(bo.dmabuf())?;
fb.render_node(

View file

@ -1,10 +1,11 @@
use {
crate::{
format::formats,
gfx_api::GfxFormat,
gfx_api::{GfxFormat, GfxWriteModifier},
ifs::jay_render_ctx::FORMATS_SINCE,
object::Version,
utils::clonecell::CloneCell,
video::Modifier,
wire::{jay_render_ctx::*, JayRenderCtxId},
wl_usr::{usr_object::UsrObject, UsrCon},
},
@ -29,6 +30,16 @@ pub trait UsrJayRenderCtxOwner {
}
}
impl UsrJayRenderCtx {
fn add_write_modifier(&self, format: u32, modifier: Modifier, needs_render_usage: bool) {
if let Some(format) = self.formats.borrow_mut().get_mut(&format) {
format
.write_modifiers
.insert(modifier, GfxWriteModifier { needs_render_usage });
}
}
}
impl JayRenderCtxEventHandler for UsrJayRenderCtx {
type Error = Infallible;
@ -57,9 +68,7 @@ impl JayRenderCtxEventHandler for UsrJayRenderCtx {
}
fn write_modifier(&self, ev: WriteModifier, _slf: &Rc<Self>) -> Result<(), Self::Error> {
if let Some(format) = self.formats.borrow_mut().get_mut(&ev.format) {
format.write_modifiers.insert(ev.modifier);
}
self.add_write_modifier(ev.format, ev.modifier, true);
Ok(())
}
@ -76,6 +85,11 @@ impl JayRenderCtxEventHandler for UsrJayRenderCtx {
}
Ok(())
}
fn write_modifier2(&self, ev: WriteModifier2, _slf: &Rc<Self>) -> Result<(), Self::Error> {
self.add_write_modifier(ev.format, ev.modifier, ev.needs_render_usage != 0);
Ok(())
}
}
usr_object_base! {

View file

@ -27,3 +27,9 @@ event write_modifier (since = 7) {
event format (since = 7) {
format: u32,
}
event write_modifier2 (since = 9) {
format: u32,
modifier: pod(u64),
needs_render_usage: u32,
}