rewrite built-in wayland compositor egl → vulkan

This commit is contained in:
galister
2025-12-25 21:26:38 +09:00
parent 3b6acb3673
commit 40dc33410d
34 changed files with 923 additions and 3051 deletions
+42 -41
View File
@@ -5,7 +5,7 @@ use std::{
};
use anyhow::Context;
use smallvec::SmallVec;
use smallvec::{SmallVec, smallvec};
use vulkano::{
VulkanError, VulkanObject,
device::Device,
@@ -19,12 +19,7 @@ use vulkano::{
sync::Sharing,
};
use wgui::gfx::WGfx;
use wlx_capture::frame::{
DRM_FORMAT_ABGR8888, DRM_FORMAT_ABGR2101010, DRM_FORMAT_ARGB8888, DRM_FORMAT_XBGR8888,
DRM_FORMAT_XBGR2101010, DRM_FORMAT_XRGB8888, DmabufFrame, DrmFormat, FourCC,
};
pub const DRM_FORMAT_MOD_INVALID: u64 = 0xff_ffff_ffff_ffff;
use wlx_capture::{DrmFormat, DrmFourcc, DrmModifier, frame::DmabufFrame};
pub trait WGfxDmabuf {
fn dmabuf_texture_ex(
@@ -47,7 +42,7 @@ impl WGfxDmabuf for WGfx {
modifiers: &[u64],
) -> anyhow::Result<Arc<Image>> {
let extent = [frame.format.width, frame.format.height, 1];
let format = fourcc_to_vk(frame.format.fourcc)?;
let format = fourcc_to_vk(frame.format.drm_format.code)?;
let image = unsafe {
create_dmabuf_image(
@@ -116,11 +111,11 @@ impl WGfxDmabuf for WGfx {
}
fn dmabuf_texture(&self, frame: DmabufFrame) -> anyhow::Result<Arc<Image>> {
let mut modifiers: Vec<u64> = vec![];
let mut modifiers: SmallVec<[u64; 4]> = smallvec![];
let mut tiling: ImageTiling = ImageTiling::Optimal;
let mut layouts: Vec<SubresourceLayout> = vec![];
if frame.format.modifier != DRM_FORMAT_MOD_INVALID {
if !matches!(frame.format.drm_format.modifier, DrmModifier::Invalid) {
(0..frame.num_planes).for_each(|i| {
let plane = &frame.planes[i];
layouts.push(SubresourceLayout {
@@ -130,7 +125,7 @@ impl WGfxDmabuf for WGfx {
array_pitch: None,
depth_pitch: None,
});
modifiers.push(frame.format.modifier);
modifiers.push(frame.format.drm_format.modifier.into());
});
tiling = ImageTiling::DrmFormatModifier;
}
@@ -304,50 +299,56 @@ pub(super) unsafe fn create_dmabuf_image(
}
}
pub fn get_drm_formats(device: Arc<Device>) -> Vec<DrmFormat> {
pub(super) fn get_drm_formats(device: Arc<Device>) -> Vec<DrmFormat> {
let possible_formats = [
DRM_FORMAT_ABGR8888.into(),
DRM_FORMAT_XBGR8888.into(),
DRM_FORMAT_ARGB8888.into(),
DRM_FORMAT_XRGB8888.into(),
DRM_FORMAT_ABGR2101010.into(),
DRM_FORMAT_XBGR2101010.into(),
DrmFourcc::Abgr8888,
DrmFourcc::Xbgr8888,
DrmFourcc::Argb8888,
DrmFourcc::Xrgb8888,
DrmFourcc::Abgr2101010,
DrmFourcc::Xbgr2101010,
];
let mut final_formats = vec![];
let mut out_formats = vec![];
for &f in &possible_formats {
let Ok(vk_fmt) = fourcc_to_vk(f) else {
for &code in &possible_formats {
let Ok(vk_fmt) = fourcc_to_vk(code) else {
continue;
};
let Ok(props) = device.physical_device().format_properties(vk_fmt) else {
continue;
};
let mut fmt = DrmFormat {
fourcc: f,
modifiers: props
.drm_format_modifier_properties
.iter()
// important bit: only allow single-plane
.filter(|m| m.drm_format_modifier_plane_count == 1)
.map(|m| m.drm_format_modifier)
.collect(),
};
fmt.modifiers.push(DRM_FORMAT_MOD_INVALID); // implicit modifiers support
final_formats.push(fmt);
for m in props
.drm_format_modifier_properties
.iter()
.filter(|m| m.drm_format_modifier_plane_count == 1)
.map(|m| m.drm_format_modifier)
{
out_formats.push(DrmFormat {
code,
modifier: DrmModifier::from(m),
});
}
// accept implicit modifiers
out_formats.push(DrmFormat {
code,
modifier: DrmModifier::Invalid,
});
}
log::debug!("Supported DRM formats:");
for f in &final_formats {
log::debug!(" {} {:?}", f.fourcc, f.modifiers);
for f in &out_formats {
log::debug!(" {} {:?}", f.code, f.modifier);
}
final_formats
out_formats
}
pub fn fourcc_to_vk(fourcc: FourCC) -> anyhow::Result<Format> {
match fourcc.value {
DRM_FORMAT_ABGR8888 | DRM_FORMAT_XBGR8888 => Ok(Format::R8G8B8A8_UNORM),
DRM_FORMAT_ARGB8888 | DRM_FORMAT_XRGB8888 => Ok(Format::B8G8R8A8_UNORM),
DRM_FORMAT_ABGR2101010 | DRM_FORMAT_XBGR2101010 => Ok(Format::A2B10G10R10_UNORM_PACK32),
pub fn fourcc_to_vk(fourcc: DrmFourcc) -> anyhow::Result<Format> {
match fourcc {
DrmFourcc::Abgr8888 | DrmFourcc::Xbgr8888 => Ok(Format::R8G8B8A8_UNORM),
DrmFourcc::Argb8888 | DrmFourcc::Xrgb8888 => Ok(Format::B8G8R8A8_UNORM),
DrmFourcc::Abgr2101010 | DrmFourcc::Xbgr2101010 => Ok(Format::A2B10G10R10_UNORM_PACK32),
_ => anyhow::bail!("Unsupported format {fourcc}"),
}
}
+25 -1
View File
@@ -19,7 +19,7 @@ use wgui::gfx::WGfx;
#[cfg(feature = "openvr")]
use vulkano::instance::InstanceCreateFlags;
use wlx_capture::frame::DrmFormat;
use wlx_capture::DrmFormat;
use crate::shaders::{frag_color, frag_grid, frag_screen, frag_srgb, vert_quad};
@@ -73,6 +73,7 @@ pub struct WGfxExtras {
pub queue_capture: Option<Arc<Queue>>,
pub quad_verts: Vert2Buf,
pub fallback_image: Arc<ImageView>,
pub drm_device: Option<(i64, i64)>,
}
impl WGfxExtras {
@@ -135,12 +136,23 @@ impl WGfxExtras {
let fallback_image = ImageView::new_default(fallback_image)?;
let p = gfx.device.physical_device().properties();
let drm_device = if let (Some(maj), Some(min)) = (p.render_major, p.render_minor) {
log::info!("DRM render device: {maj} {min}");
Some((maj, min))
} else {
log::warn!("No DRM device.");
None
};
Ok(Self {
shaders,
drm_formats,
queue_capture,
quad_verts,
fallback_image,
drm_device,
})
}
}
@@ -271,6 +283,13 @@ pub fn init_openxr_graphics(
.ext_image_drm_format_modifier;
}
if physical_device
.supported_extensions()
.ext_physical_device_drm
{
device_extensions.ext_physical_device_drm = true;
}
let device_extensions_raw = device_extensions
.into_iter()
.filter_map(|(name, enabled)| {
@@ -432,6 +451,11 @@ pub fn init_openvr_graphics(
my_extensions.ext_filter_cubic = true;
}
if p.supported_extensions().ext_physical_device_drm {
// needed for wayland_server
my_extensions.ext_physical_device_drm = true;
}
log::debug!(
"Device exts for {}: {:?}",
p.properties().device_name,