rewrite built-in wayland compositor egl → vulkan
This commit is contained in:
@@ -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}"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user