diff --git a/src/wayland/dmabuf/feedback.rs b/src/wayland/dmabuf/feedback.rs index ee0ab43..c18455f 100644 --- a/src/wayland/dmabuf/feedback.rs +++ b/src/wayland/dmabuf/feedback.rs @@ -1,3 +1,4 @@ +use bevy_dmabuf::format_mapping::{drm_fourcc_to_vk_format, vk_format_to_drm_fourcc}; use drm_fourcc::DrmFourcc; use memfd::MemfdOptions; use std::{ @@ -14,12 +15,38 @@ use waynest::{ wire::ObjectId, }; +use crate::wayland::vulkano_data::{DMA_CAPABLE_FORMATS, VULKANO_CONTEXT}; + #[derive(Debug, Dispatcher)] pub struct DmabufFeedback; impl DmabufFeedback { pub async fn send_params(&self, client: &mut Client, sender_id: ObjectId) -> Result<()> { + let vk = VULKANO_CONTEXT.wait(); + let formats = DMA_CAPABLE_FORMATS + .iter() + .filter(|f| { + vk_format_to_drm_fourcc((**f).into()) + .and_then(drm_fourcc_to_vk_format) + .is_some() + }) + .filter_map(|f| { + Some(( + vk_format_to_drm_fourcc((*f).into())?, + vk.phys_dev + .format_properties(*f) + .ok()? + .drm_format_modifier_properties + .into_iter() + .map(|v| v.drm_format_modifier) + .collect::>(), + )) + }) + .flat_map(|(f, mods)| mods.into_iter().map(move |modifier| (f, modifier))) + .collect::>(); + + let num_formats = formats.len(); // Send format table first - self.send_format_table(client, sender_id).await?; + self.send_format_table(client, sender_id, formats).await?; // let graphics_info = &client.display().graphics_info; @@ -35,11 +62,16 @@ impl DmabufFeedback { // self.tranche_target_device(client, sender_id, dev_id) // .await?; + // let props = vk.phys_dev.properties(); + // tracing::info!( + // props.primary_major, + // props.primary_minor, + // props.render_major, + // props.render_minor + // ); + // We only have one format at index 0 - let indices = vec![0u16] - .into_iter() - .flat_map(|i| i.to_ne_bytes()) - .collect(); + let indices = (0..num_formats).flat_map(|i| i.to_ne_bytes()).collect(); self.tranche_formats(client, sender_id, indices).await?; // No special flags needed for simple EGL texture usage @@ -54,25 +86,30 @@ impl DmabufFeedback { Ok(()) } - pub async fn send_format_table(&self, client: &mut Client, sender_id: ObjectId) -> Result<()> { + pub async fn send_format_table( + &self, + client: &mut Client, + sender_id: ObjectId, + formats: Vec<(DrmFourcc, u64)>, + ) -> Result<()> { + // Format + modifier pair (16 bytes): + // - format: u32 + // - padding: 4 bytes + // - modifier: u64 + let size = formats.len() as u32 * 16u32; // Create a temporary file for the format table - let size = 16u32; // One format+modifier pair let mfd = MemfdOptions::default() .create("stardustxr-format-table") .map_err(|e| waynest::server::Error::Custom(e.to_string()))?; mfd.as_file().set_len(size as u64)?; - // Format + modifier pair (16 bytes): - // - format: u32 - // - padding: 4 bytes - // - modifier: u64 - let format = DrmFourcc::Xrgb8888 as u32; // This is what clients typically want - let modifier: u64 = 0; // Linear modifier - - // Write the format+modifier pair - mfd.as_file().write_all(&format.to_ne_bytes())?; - mfd.as_file().write_all(&modifier.to_ne_bytes())?; + for (format, modifier) in formats { + let format = format as u32; + // Write the format+modifier pair + mfd.as_file().write_all(&format.to_ne_bytes())?; + mfd.as_file().write_all(&modifier.to_ne_bytes())?; + } self.format_table( client, diff --git a/src/wayland/vulkano_data.rs b/src/wayland/vulkano_data.rs index d4de7f1..feb75b2 100644 --- a/src/wayland/vulkano_data.rs +++ b/src/wayland/vulkano_data.rs @@ -11,6 +11,7 @@ use vulkano::{ StandardCommandBufferAllocatorCreateInfo, }, device::{DeviceCreateInfo, QueueCreateInfo}, + format::Format, instance::InstanceCreateFlags, memory::allocator::{MemoryAllocator, StandardMemoryAllocator}, }; @@ -140,3 +141,34 @@ unsafe impl vulkano::library::Loader for AshEntryVulkanoLoader { unsafe { self.0.get_instance_proc_addr(instance, name) } } } + +pub const DMA_CAPABLE_FORMATS: [Format; 28] = [ + Format::A2B10G10R10_UNORM_PACK32, + Format::A2B10G10R10_SINT_PACK32, + Format::A2R10G10B10_UNORM_PACK32, + Format::A2R10G10B10_SINT_PACK32, + Format::B8G8R8_UNORM, + Format::B8G8R8_SINT, + Format::R8G8B8A8_UNORM, + Format::R8G8B8A8_SINT, + Format::R8G8B8_UNORM, + Format::R8G8B8_SINT, + Format::B8G8R8A8_UNORM, + Format::B8G8R8A8_SINT, + Format::R16_UNORM, + Format::R16_SINT, + Format::R8_UNORM, + Format::R8_SINT, + Format::R16G16_UNORM, + Format::R16G16_SINT, + Format::R8G8_UNORM, + Format::R8G8_SINT, + Format::A4B4G4R4_UNORM_PACK16, + Format::A1R5G5B5_UNORM_PACK16, + Format::B5G6R5_UNORM_PACK16, + Format::B4G4R4A4_UNORM_PACK16, + Format::B5G5R5A1_UNORM_PACK16, + Format::R5G6B5_UNORM_PACK16, + Format::R4G4B4A4_UNORM_PACK16, + Format::R5G5B5A1_UNORM_PACK16, +];