reuse wgfxpass on wayvr+screen
This commit is contained in:
@@ -202,24 +202,6 @@ impl WGfx {
|
|||||||
)?))
|
)?))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_pipeline_procedural(
|
|
||||||
self: &Arc<Self>,
|
|
||||||
vert: Arc<ShaderModule>,
|
|
||||||
frag: Arc<ShaderModule>,
|
|
||||||
format: Format,
|
|
||||||
blend: Option<AttachmentBlend>,
|
|
||||||
topology: PrimitiveTopology,
|
|
||||||
) -> anyhow::Result<Arc<WGfxPipeline<()>>> {
|
|
||||||
Ok(Arc::new(WGfxPipeline::new_procedural(
|
|
||||||
self.clone(),
|
|
||||||
vert,
|
|
||||||
frag,
|
|
||||||
format,
|
|
||||||
blend,
|
|
||||||
topology,
|
|
||||||
)?))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_gfx_command_buffer(
|
pub fn create_gfx_command_buffer(
|
||||||
self: &Arc<Self>,
|
self: &Arc<Self>,
|
||||||
usage: CommandBufferUsage,
|
usage: CommandBufferUsage,
|
||||||
|
|||||||
@@ -2,135 +2,36 @@ use std::{marker::PhantomData, ops::Range, sync::Arc};
|
|||||||
|
|
||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{BufferContents, IndexBuffer, Subbuffer},
|
buffer::{BufferContents, Subbuffer},
|
||||||
command_buffer::{
|
command_buffer::{
|
||||||
AutoCommandBufferBuilder, CommandBufferInheritanceInfo, CommandBufferInheritanceRenderPassType,
|
AutoCommandBufferBuilder, CommandBufferInheritanceInfo, CommandBufferInheritanceRenderPassType,
|
||||||
CommandBufferInheritanceRenderingInfo, CommandBufferUsage, SecondaryAutoCommandBuffer,
|
CommandBufferInheritanceRenderingInfo, CommandBufferUsage, SecondaryAutoCommandBuffer,
|
||||||
},
|
},
|
||||||
descriptor_set::DescriptorSet,
|
descriptor_set::{DescriptorSet, WriteDescriptorSet},
|
||||||
|
image::{
|
||||||
|
sampler::{Filter, Sampler, SamplerAddressMode, SamplerCreateInfo},
|
||||||
|
view::ImageView,
|
||||||
|
},
|
||||||
pipeline::{
|
pipeline::{
|
||||||
Pipeline, PipelineBindPoint,
|
Pipeline, PipelineBindPoint,
|
||||||
graphics::{vertex_input::Vertex, viewport::Viewport},
|
graphics::{vertex_input::Vertex, viewport::Viewport},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::pipeline::WGfxPipeline;
|
use super::{WGfx, pipeline::WGfxPipeline};
|
||||||
|
|
||||||
pub struct WGfxPass<V> {
|
pub struct WGfxPass<V> {
|
||||||
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
|
pub command_buffer: Arc<SecondaryAutoCommandBuffer>,
|
||||||
_dummy: PhantomData<V>,
|
graphics: Arc<WGfx>,
|
||||||
}
|
|
||||||
|
|
||||||
impl WGfxPass<()> {
|
|
||||||
pub(super) fn new_procedural(
|
|
||||||
pipeline: Arc<WGfxPipeline<()>>,
|
|
||||||
dimensions: [f32; 2],
|
|
||||||
vertices: Range<u32>,
|
|
||||||
instances: Range<u32>,
|
|
||||||
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
||||||
) -> anyhow::Result<Self> {
|
_dummy: PhantomData<V>,
|
||||||
let viewport = Viewport {
|
|
||||||
offset: [0.0, 0.0],
|
|
||||||
extent: dimensions,
|
|
||||||
depth_range: 0.0..=1.0,
|
|
||||||
};
|
|
||||||
let pipeline_inner = pipeline.inner();
|
|
||||||
let mut command_buffer = AutoCommandBufferBuilder::secondary(
|
|
||||||
pipeline.graphics.command_buffer_allocator.clone(),
|
|
||||||
pipeline.graphics.queue_gfx.queue_family_index(),
|
|
||||||
CommandBufferUsage::MultipleSubmit,
|
|
||||||
CommandBufferInheritanceInfo {
|
|
||||||
render_pass: Some(CommandBufferInheritanceRenderPassType::BeginRendering(
|
|
||||||
CommandBufferInheritanceRenderingInfo {
|
|
||||||
color_attachment_formats: vec![Some(pipeline.format)],
|
|
||||||
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
command_buffer
|
|
||||||
.set_viewport(0, smallvec![viewport])?
|
|
||||||
.bind_pipeline_graphics(pipeline_inner)?
|
|
||||||
.bind_descriptor_sets(
|
|
||||||
PipelineBindPoint::Graphics,
|
|
||||||
pipeline.inner().layout().clone(),
|
|
||||||
0,
|
|
||||||
descriptor_sets,
|
|
||||||
)?
|
|
||||||
.draw(
|
|
||||||
vertices.end - vertices.start,
|
|
||||||
instances.end - instances.start,
|
|
||||||
vertices.start,
|
|
||||||
instances.start,
|
|
||||||
)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
command_buffer: command_buffer.build()?,
|
|
||||||
_dummy: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V> WGfxPass<V>
|
impl<V> WGfxPass<V>
|
||||||
where
|
where
|
||||||
V: BufferContents + Vertex,
|
V: BufferContents + Vertex,
|
||||||
{
|
{
|
||||||
pub(super) fn new_indexed(
|
pub(super) fn new(
|
||||||
pipeline: Arc<WGfxPipeline<V>>,
|
|
||||||
dimensions: [f32; 2],
|
|
||||||
vertex_buffer: Subbuffer<[V]>,
|
|
||||||
index_buffer: IndexBuffer,
|
|
||||||
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
|
||||||
) -> anyhow::Result<Self> {
|
|
||||||
let viewport = Viewport {
|
|
||||||
offset: [0.0, 0.0],
|
|
||||||
extent: dimensions,
|
|
||||||
depth_range: 0.0..=1.0,
|
|
||||||
};
|
|
||||||
let pipeline_inner = pipeline.inner();
|
|
||||||
let mut command_buffer = AutoCommandBufferBuilder::secondary(
|
|
||||||
pipeline.graphics.command_buffer_allocator.clone(),
|
|
||||||
pipeline.graphics.queue_gfx.queue_family_index(),
|
|
||||||
CommandBufferUsage::MultipleSubmit,
|
|
||||||
CommandBufferInheritanceInfo {
|
|
||||||
render_pass: Some(CommandBufferInheritanceRenderPassType::BeginRendering(
|
|
||||||
CommandBufferInheritanceRenderingInfo {
|
|
||||||
color_attachment_formats: vec![Some(pipeline.format)],
|
|
||||||
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
command_buffer
|
|
||||||
.set_viewport(0, smallvec![viewport])?
|
|
||||||
.bind_pipeline_graphics(pipeline_inner)?
|
|
||||||
.bind_descriptor_sets(
|
|
||||||
PipelineBindPoint::Graphics,
|
|
||||||
pipeline.inner().layout().clone(),
|
|
||||||
0,
|
|
||||||
descriptor_sets,
|
|
||||||
)?
|
|
||||||
.bind_vertex_buffers(0, vertex_buffer)?
|
|
||||||
.bind_index_buffer(index_buffer.clone())?
|
|
||||||
.draw_indexed(index_buffer.len() as u32, 1, 0, 0, 0)?
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(Self {
|
|
||||||
command_buffer: command_buffer.build()?,
|
|
||||||
_dummy: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn new_instanced(
|
|
||||||
pipeline: Arc<WGfxPipeline<V>>,
|
pipeline: Arc<WGfxPipeline<V>>,
|
||||||
dimensions: [f32; 2],
|
dimensions: [f32; 2],
|
||||||
vertex_buffer: Subbuffer<[V]>,
|
vertex_buffer: Subbuffer<[V]>,
|
||||||
@@ -168,7 +69,7 @@ where
|
|||||||
PipelineBindPoint::Graphics,
|
PipelineBindPoint::Graphics,
|
||||||
pipeline.inner().layout().clone(),
|
pipeline.inner().layout().clone(),
|
||||||
0,
|
0,
|
||||||
descriptor_sets,
|
descriptor_sets.clone(),
|
||||||
)?
|
)?
|
||||||
.bind_vertex_buffers(0, vertex_buffer)?
|
.bind_vertex_buffers(0, vertex_buffer)?
|
||||||
.draw(
|
.draw(
|
||||||
@@ -181,7 +82,35 @@ where
|
|||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
command_buffer: command_buffer.build()?,
|
command_buffer: command_buffer.build()?,
|
||||||
|
graphics: pipeline.graphics.clone(),
|
||||||
|
descriptor_sets,
|
||||||
_dummy: PhantomData,
|
_dummy: PhantomData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_sampler(
|
||||||
|
&self,
|
||||||
|
set: usize,
|
||||||
|
texture: Arc<ImageView>,
|
||||||
|
filter: Filter,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let sampler = Sampler::new(
|
||||||
|
self.graphics.device.clone(),
|
||||||
|
SamplerCreateInfo {
|
||||||
|
mag_filter: filter,
|
||||||
|
min_filter: filter,
|
||||||
|
address_mode: [SamplerAddressMode::Repeat; 3],
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
self.descriptor_sets[set].update_by_ref(
|
||||||
|
[WriteDescriptorSet::image_view_sampler(0, texture, sampler)],
|
||||||
|
[],
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::{marker::PhantomData, ops::Range, sync::Arc};
|
|||||||
use smallvec::smallvec;
|
use smallvec::smallvec;
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{
|
buffer::{
|
||||||
BufferContents, BufferUsage, IndexBuffer, Subbuffer,
|
BufferContents, BufferUsage, Subbuffer,
|
||||||
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
allocator::{SubbufferAllocator, SubbufferAllocatorCreateInfo},
|
||||||
},
|
},
|
||||||
descriptor_set::{DescriptorSet, WriteDescriptorSet},
|
descriptor_set::{DescriptorSet, WriteDescriptorSet},
|
||||||
@@ -177,46 +177,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WGfxPipeline<()> {
|
|
||||||
pub(super) fn new_procedural(
|
|
||||||
graphics: Arc<WGfx>,
|
|
||||||
vert: Arc<ShaderModule>,
|
|
||||||
frag: Arc<ShaderModule>,
|
|
||||||
format: Format,
|
|
||||||
blend: Option<AttachmentBlend>,
|
|
||||||
topology: PrimitiveTopology,
|
|
||||||
) -> anyhow::Result<Self> {
|
|
||||||
let vert_entry_point = vert.entry_point("main").unwrap(); // want panic
|
|
||||||
let frag_entry_point = frag.entry_point("main").unwrap(); // want panic
|
|
||||||
|
|
||||||
WGfxPipeline::new_from_stages(
|
|
||||||
graphics,
|
|
||||||
format,
|
|
||||||
blend,
|
|
||||||
topology,
|
|
||||||
vert_entry_point,
|
|
||||||
frag_entry_point,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_pass_procedural(
|
|
||||||
self: &Arc<Self>,
|
|
||||||
dimensions: [f32; 2],
|
|
||||||
vertices: Range<u32>,
|
|
||||||
instances: Range<u32>,
|
|
||||||
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
|
||||||
) -> anyhow::Result<WGfxPass<()>> {
|
|
||||||
WGfxPass::new_procedural(
|
|
||||||
self.clone(),
|
|
||||||
dimensions,
|
|
||||||
vertices,
|
|
||||||
instances,
|
|
||||||
descriptor_sets,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<V> WGfxPipeline<V>
|
impl<V> WGfxPipeline<V>
|
||||||
where
|
where
|
||||||
V: BufferContents + Vertex,
|
V: BufferContents + Vertex,
|
||||||
@@ -258,7 +218,7 @@ where
|
|||||||
instances: Range<u32>,
|
instances: Range<u32>,
|
||||||
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
||||||
) -> anyhow::Result<WGfxPass<V>> {
|
) -> anyhow::Result<WGfxPass<V>> {
|
||||||
WGfxPass::new_instanced(
|
WGfxPass::new(
|
||||||
self.clone(),
|
self.clone(),
|
||||||
dimensions,
|
dimensions,
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
@@ -267,20 +227,4 @@ where
|
|||||||
descriptor_sets,
|
descriptor_sets,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_pass_indexed(
|
|
||||||
self: &Arc<Self>,
|
|
||||||
dimensions: [f32; 2],
|
|
||||||
vertex_buffer: Subbuffer<[V]>,
|
|
||||||
index_buffer: IndexBuffer,
|
|
||||||
descriptor_sets: Vec<Arc<DescriptorSet>>,
|
|
||||||
) -> anyhow::Result<WGfxPass<V>> {
|
|
||||||
WGfxPass::new_indexed(
|
|
||||||
self.clone(),
|
|
||||||
dimensions,
|
|
||||||
vertex_buffer,
|
|
||||||
index_buffer,
|
|
||||||
descriptor_sets,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ impl RectRenderer {
|
|||||||
|
|
||||||
let set0 = viewport.get_rect_descriptor(&self.pipeline);
|
let set0 = viewport.get_rect_descriptor(&self.pipeline);
|
||||||
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
|
let set1 = self.model_buffer.get_rect_descriptor(&self.pipeline);
|
||||||
|
|
||||||
let pass = self.pipeline.color_rect.create_pass(
|
let pass = self.pipeline.color_rect.create_pass(
|
||||||
[vp[0] as _, vp[1] as _],
|
[vp[0] as _, vp[1] as _],
|
||||||
self.vert_buffer.clone(),
|
self.vert_buffer.clone(),
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ use wgui::gfx::{WGfx, pass::WGfxPass, pipeline::WGfxPipeline};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::openxr::helpers,
|
backend::openxr::helpers,
|
||||||
graphics::{CommandBuffers, ExtentExt, Vert2Uv},
|
graphics::{CommandBuffers, Vert2Uv},
|
||||||
state::AppState,
|
state::AppState,
|
||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use std::{
|
|||||||
use glam::{Vec2, vec2};
|
use glam::{Vec2, vec2};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
buffer::{BufferCreateInfo, BufferUsage},
|
buffer::{BufferCreateInfo, BufferUsage},
|
||||||
command_buffer::{PrimaryAutoCommandBuffer, PrimaryCommandBufferAbstract},
|
command_buffer::{CommandBufferUsage, PrimaryAutoCommandBuffer, PrimaryCommandBufferAbstract},
|
||||||
image::view::ImageView,
|
image::view::ImageView,
|
||||||
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter},
|
memory::allocator::{AllocationCreateInfo, MemoryTypeFilter},
|
||||||
sync::GpuFuture,
|
sync::GpuFuture,
|
||||||
@@ -72,10 +72,11 @@ pub struct WGfxExtras {
|
|||||||
pub drm_formats: Vec<DrmFormat>,
|
pub drm_formats: Vec<DrmFormat>,
|
||||||
pub queue_capture: Option<Arc<Queue>>,
|
pub queue_capture: Option<Arc<Queue>>,
|
||||||
pub quad_verts: Vert2Buf,
|
pub quad_verts: Vert2Buf,
|
||||||
|
pub fallback_image: Arc<ImageView>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WGfxExtras {
|
impl WGfxExtras {
|
||||||
pub fn new(gfx: &WGfx, queue_capture: Option<Arc<Queue>>) -> anyhow::Result<Self> {
|
pub fn new(gfx: Arc<WGfx>, queue_capture: Option<Arc<Queue>>) -> anyhow::Result<Self> {
|
||||||
let mut shaders = HashMap::new();
|
let mut shaders = HashMap::new();
|
||||||
|
|
||||||
let shader = vert_quad::load(gfx.device.clone())?;
|
let shader = vert_quad::load(gfx.device.clone())?;
|
||||||
@@ -127,11 +128,19 @@ impl WGfxExtras {
|
|||||||
vertices.into_iter(),
|
vertices.into_iter(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let mut cmd_xfer = gfx.create_xfer_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
|
let fallback_image =
|
||||||
|
cmd_xfer.upload_image(1, 1, Format::R8G8B8A8_SRGB, &[255, 0, 255, 255])?;
|
||||||
|
cmd_xfer.build_and_execute_now()?;
|
||||||
|
|
||||||
|
let fallback_image = ImageView::new_default(fallback_image)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
shaders,
|
shaders,
|
||||||
drm_formats,
|
drm_formats,
|
||||||
queue_capture,
|
queue_capture,
|
||||||
quad_verts,
|
quad_verts,
|
||||||
|
fallback_image,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -354,7 +363,7 @@ pub fn init_openxr_graphics(
|
|||||||
queue_xfer,
|
queue_xfer,
|
||||||
Format::R8G8B8A8_SRGB,
|
Format::R8G8B8A8_SRGB,
|
||||||
);
|
);
|
||||||
let extras = WGfxExtras::new(&gfx, queue_capture)?;
|
let extras = WGfxExtras::new(gfx.clone(), queue_capture)?;
|
||||||
|
|
||||||
Ok((gfx, extras))
|
Ok((gfx, extras))
|
||||||
}
|
}
|
||||||
@@ -471,7 +480,7 @@ pub fn init_openvr_graphics(
|
|||||||
queue_xfer,
|
queue_xfer,
|
||||||
Format::R8G8B8A8_SRGB,
|
Format::R8G8B8A8_SRGB,
|
||||||
);
|
);
|
||||||
let extras = WGfxExtras::new(&gfx, queue_capture)?;
|
let extras = WGfxExtras::new(gfx.clone(), queue_capture)?;
|
||||||
|
|
||||||
Ok((gfx, extras))
|
Ok((gfx, extras))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use std::{
|
use std::{
|
||||||
f32::consts::PI,
|
f32::consts::PI,
|
||||||
ptr,
|
ptr,
|
||||||
sync::{atomic::AtomicU64, Arc, LazyLock},
|
sync::{Arc, LazyLock, atomic::AtomicU64},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
@@ -11,15 +11,15 @@ use vulkano::{
|
|||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
device::Queue,
|
device::Queue,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{sampler::Filter, view::ImageView, Image},
|
image::{Image, sampler::Filter, view::ImageView},
|
||||||
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
pipeline::graphics::{color_blend::AttachmentBlend, input_assembly::PrimitiveTopology},
|
||||||
};
|
};
|
||||||
use wgui::gfx::{cmd::XferCommandBuffer, pass::WGfxPass, pipeline::WGfxPipeline, WGfx};
|
use wgui::gfx::{WGfx, cmd::XferCommandBuffer, pass::WGfxPass, pipeline::WGfxPipeline};
|
||||||
use wlx_capture::frame as wlx_frame;
|
use wlx_capture::frame as wlx_frame;
|
||||||
|
|
||||||
use wlx_capture::{
|
use wlx_capture::{
|
||||||
frame::{FrameFormat, MouseMeta, WlxFrame},
|
|
||||||
WlxCapture,
|
WlxCapture,
|
||||||
|
frame::{FrameFormat, MouseMeta, WlxFrame},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(feature = "pipewire")]
|
#[cfg(feature = "pipewire")]
|
||||||
@@ -38,7 +38,7 @@ use wlx_capture::pipewire::PipewireStream;
|
|||||||
use {
|
use {
|
||||||
crate::config::AStrMapExt,
|
crate::config::AStrMapExt,
|
||||||
wlx_capture::{
|
wlx_capture::{
|
||||||
wayland::{wayland_client::protocol::wl_output, WlxClient, WlxOutput},
|
wayland::{WlxClient, WlxOutput, wayland_client::protocol::wl_output},
|
||||||
wlr_dmabuf::WlrDmabufCapture,
|
wlr_dmabuf::WlrDmabufCapture,
|
||||||
wlr_screencopy::WlrScreencopyCapture,
|
wlr_screencopy::WlrScreencopyCapture,
|
||||||
},
|
},
|
||||||
@@ -47,7 +47,7 @@ use {
|
|||||||
#[cfg(feature = "x11")]
|
#[cfg(feature = "x11")]
|
||||||
use wlx_capture::xshm::{XshmCapture, XshmScreen};
|
use wlx_capture::xshm::{XshmCapture, XshmScreen};
|
||||||
|
|
||||||
use glam::{vec2, vec3a, Affine2, Affine3A, Quat, Vec2, Vec3};
|
use glam::{Affine2, Affine3A, Quat, Vec2, Vec3, vec2, vec3a};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::{
|
backend::{
|
||||||
@@ -57,10 +57,11 @@ use crate::{
|
|||||||
SplitOverlayBackend,
|
SplitOverlayBackend,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config::{def_pw_tokens, GeneralConfig, PwTokenMap},
|
config::{GeneralConfig, PwTokenMap, def_pw_tokens},
|
||||||
graphics::{
|
graphics::{
|
||||||
dmabuf::{fourcc_to_vk, WGfxDmabuf},
|
CommandBuffers, Vert2Uv,
|
||||||
upload_quad_vertices, CommandBuffers, ExtentExt, Vert2Uv,
|
dmabuf::{WGfxDmabuf, fourcc_to_vk},
|
||||||
|
upload_quad_vertices,
|
||||||
},
|
},
|
||||||
hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
hid::{MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT},
|
||||||
state::{AppSession, AppState, KeyboardFocus, ScreenMeta},
|
state::{AppSession, AppState, KeyboardFocus, ScreenMeta},
|
||||||
@@ -166,12 +167,15 @@ struct MousePass {
|
|||||||
struct ScreenPipeline {
|
struct ScreenPipeline {
|
||||||
mouse: Option<MousePass>,
|
mouse: Option<MousePass>,
|
||||||
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
||||||
|
pass: WGfxPass<Vert2Uv>,
|
||||||
buf_alpha: Subbuffer<[f32]>,
|
buf_alpha: Subbuffer<[f32]>,
|
||||||
extentf: [f32; 2],
|
extentf: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScreenPipeline {
|
impl ScreenPipeline {
|
||||||
fn new(extent: &[u32; 3], app: &mut AppState) -> anyhow::Result<Self> {
|
fn new(extent: &[u32; 3], app: &mut AppState) -> anyhow::Result<Self> {
|
||||||
|
let extentf = [extent[0] as f32, extent[1] as f32];
|
||||||
|
|
||||||
let pipeline = app.gfx.create_pipeline(
|
let pipeline = app.gfx.create_pipeline(
|
||||||
app.gfx_extras.shaders.get("vert_quad").unwrap().clone(), // want panic
|
app.gfx_extras.shaders.get("vert_quad").unwrap().clone(), // want panic
|
||||||
app.gfx_extras.shaders.get("frag_screen").unwrap().clone(), // want panic
|
app.gfx_extras.shaders.get("frag_screen").unwrap().clone(), // want panic
|
||||||
@@ -185,11 +189,25 @@ impl ScreenPipeline {
|
|||||||
.gfx
|
.gfx
|
||||||
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::UNIFORM_BUFFER, 1)?;
|
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::UNIFORM_BUFFER, 1)?;
|
||||||
|
|
||||||
let extentf = [extent[0] as f32, extent[1] as f32];
|
let set0 = pipeline.uniform_sampler(
|
||||||
|
0,
|
||||||
|
app.gfx_extras.fallback_image.clone(),
|
||||||
|
app.gfx.texture_filter,
|
||||||
|
)?;
|
||||||
|
let set1 = pipeline.buffer(1, buf_alpha.clone())?;
|
||||||
|
|
||||||
|
let pass = pipeline.create_pass(
|
||||||
|
extentf,
|
||||||
|
app.gfx_extras.quad_verts.clone(),
|
||||||
|
0..4,
|
||||||
|
0..1,
|
||||||
|
vec![set0.clone(), set1],
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
mouse: None,
|
mouse: None,
|
||||||
pipeline,
|
pipeline,
|
||||||
|
pass,
|
||||||
buf_alpha,
|
buf_alpha,
|
||||||
extentf,
|
extentf,
|
||||||
})
|
})
|
||||||
@@ -243,26 +261,15 @@ impl ScreenPipeline {
|
|||||||
alpha: f32,
|
alpha: f32,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let view = ImageView::new_default(image)?;
|
let view = ImageView::new_default(image)?;
|
||||||
let set0 = self
|
|
||||||
.pipeline
|
|
||||||
.uniform_sampler(0, view, app.gfx.texture_filter)?;
|
|
||||||
|
|
||||||
|
self.pass.update_sampler(0, view, app.gfx.texture_filter)?;
|
||||||
self.buf_alpha.write()?[0] = alpha;
|
self.buf_alpha.write()?[0] = alpha;
|
||||||
|
|
||||||
let set1 = self.pipeline.buffer(1, self.buf_alpha.clone())?;
|
|
||||||
let pass = self.pipeline.create_pass(
|
|
||||||
tgt.extent_f32(),
|
|
||||||
app.gfx_extras.quad_verts.clone(),
|
|
||||||
0..4,
|
|
||||||
0..1,
|
|
||||||
vec![set0, set1],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut cmd = app
|
let mut cmd = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd.begin_rendering(tgt)?;
|
cmd.begin_rendering(tgt)?;
|
||||||
cmd.run_ref(&pass)?;
|
cmd.run_ref(&self.pass)?;
|
||||||
|
|
||||||
if let (Some(mouse), Some(pass)) = (mouse, self.mouse.as_mut()) {
|
if let (Some(mouse), Some(pass)) = (mouse, self.mouse.as_mut()) {
|
||||||
let size = CURSOR_SIZE * self.extentf[1];
|
let size = CURSOR_SIZE * self.extentf[1];
|
||||||
@@ -542,20 +549,26 @@ impl OverlayRenderer for ScreenRenderer {
|
|||||||
let dmabuf_formats = if !supports_dmabuf {
|
let dmabuf_formats = if !supports_dmabuf {
|
||||||
log::info!("Capture method does not support DMA-buf");
|
log::info!("Capture method does not support DMA-buf");
|
||||||
if app.gfx_extras.queue_capture.is_none() {
|
if app.gfx_extras.queue_capture.is_none() {
|
||||||
log::warn!("Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance.");
|
log::warn!(
|
||||||
|
"Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
&Vec::new()
|
&Vec::new()
|
||||||
} else if !allow_dmabuf {
|
} else if !allow_dmabuf {
|
||||||
log::info!("Not using DMA-buf capture due to {capture_method}");
|
log::info!("Not using DMA-buf capture due to {capture_method}");
|
||||||
if app.gfx_extras.queue_capture.is_none() {
|
if app.gfx_extras.queue_capture.is_none() {
|
||||||
log::warn!("Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance.");
|
log::warn!(
|
||||||
|
"Current GPU does not support multiple queues. Software capture will take place on the main thread. Expect degraded performance."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
&Vec::new()
|
&Vec::new()
|
||||||
} else {
|
} else {
|
||||||
log::warn!(
|
log::warn!(
|
||||||
"Using DMA-buf capture. If screens are blank for you, switch to SHM using:"
|
"Using DMA-buf capture. If screens are blank for you, switch to SHM using:"
|
||||||
);
|
);
|
||||||
log::warn!("echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml");
|
log::warn!(
|
||||||
|
"echo 'capture_method: pw_fallback' > ~/.config/wlxoverlay/conf.d/pw_fallback.yaml"
|
||||||
|
);
|
||||||
|
|
||||||
&app.gfx_extras.drm_formats
|
&app.gfx_extras.drm_formats
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
use glam::{vec3a, Affine2, Vec3, Vec3A};
|
use glam::{Affine2, Vec3, Vec3A, vec3a};
|
||||||
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::Arc};
|
||||||
use vulkano::{
|
use vulkano::{
|
||||||
|
buffer::{BufferUsage, Subbuffer},
|
||||||
command_buffer::CommandBufferUsage,
|
command_buffer::CommandBufferUsage,
|
||||||
format::Format,
|
format::Format,
|
||||||
image::{view::ImageView, Image, ImageTiling, SubresourceLayout},
|
image::{Image, ImageTiling, SubresourceLayout, view::ImageView},
|
||||||
pipeline::graphics::input_assembly::PrimitiveTopology,
|
pipeline::graphics::input_assembly::PrimitiveTopology,
|
||||||
};
|
};
|
||||||
use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged};
|
use wayvr_ipc::packet_server::{self, PacketServer, WvrStateChanged};
|
||||||
use wgui::gfx::{pipeline::WGfxPipeline, WGfx};
|
use wgui::gfx::{WGfx, pass::WGfxPass, pipeline::WGfxPipeline};
|
||||||
use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane};
|
use wlx_capture::frame::{DmabufFrame, FourCC, FrameFormat, FramePlane};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -15,18 +16,17 @@ use crate::{
|
|||||||
common::{OverlayContainer, OverlaySelector},
|
common::{OverlayContainer, OverlaySelector},
|
||||||
input::{self, InteractionHandler},
|
input::{self, InteractionHandler},
|
||||||
overlay::{
|
overlay::{
|
||||||
ui_transform, FrameMeta, OverlayData, OverlayID, OverlayRenderer, OverlayState,
|
FrameMeta, OverlayData, OverlayID, OverlayRenderer, OverlayState, ShouldRender,
|
||||||
ShouldRender, SplitOverlayBackend, Z_ORDER_DASHBOARD,
|
SplitOverlayBackend, Z_ORDER_DASHBOARD, ui_transform,
|
||||||
},
|
},
|
||||||
task::TaskType,
|
task::TaskType,
|
||||||
wayvr::{
|
wayvr::{
|
||||||
self, display,
|
self, WayVR, WayVRAction, WayVRDisplayClickAction, display,
|
||||||
server_ipc::{gen_args_vec, gen_env_vec},
|
server_ipc::{gen_args_vec, gen_env_vec},
|
||||||
WayVR, WayVRAction, WayVRDisplayClickAction,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
config_wayvr,
|
config_wayvr,
|
||||||
graphics::{dmabuf::WGfxDmabuf, CommandBuffers, ExtentExt, Vert2Uv},
|
graphics::{CommandBuffers, Vert2Uv, dmabuf::WGfxDmabuf},
|
||||||
state::{self, AppState, KeyboardFocus},
|
state::{self, AppState, KeyboardFocus},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -183,6 +183,8 @@ struct ImageData {
|
|||||||
|
|
||||||
pub struct WayVRRenderer {
|
pub struct WayVRRenderer {
|
||||||
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
pipeline: Arc<WGfxPipeline<Vert2Uv>>,
|
||||||
|
pass: WGfxPass<Vert2Uv>,
|
||||||
|
buf_alpha: Subbuffer<[f32]>,
|
||||||
image: Option<ImageData>,
|
image: Option<ImageData>,
|
||||||
context: Rc<RefCell<WayVRContext>>,
|
context: Rc<RefCell<WayVRContext>>,
|
||||||
graphics: Arc<WGfx>,
|
graphics: Arc<WGfx>,
|
||||||
@@ -205,8 +207,28 @@ impl WayVRRenderer {
|
|||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
let buf_alpha = app
|
||||||
|
.gfx
|
||||||
|
.empty_buffer(BufferUsage::TRANSFER_DST | BufferUsage::UNIFORM_BUFFER, 1)?;
|
||||||
|
|
||||||
|
let set0 = pipeline.uniform_sampler(
|
||||||
|
0,
|
||||||
|
app.gfx_extras.fallback_image.clone(),
|
||||||
|
app.gfx.texture_filter,
|
||||||
|
)?;
|
||||||
|
let set1 = pipeline.buffer(1, buf_alpha.clone())?;
|
||||||
|
let pass = pipeline.create_pass(
|
||||||
|
[resolution[0] as _, resolution[1] as _],
|
||||||
|
app.gfx_extras.quad_verts.clone(),
|
||||||
|
0..4,
|
||||||
|
0..1,
|
||||||
|
vec![set0, set1],
|
||||||
|
)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pipeline,
|
pipeline,
|
||||||
|
pass,
|
||||||
|
buf_alpha,
|
||||||
context: Rc::new(RefCell::new(WayVRContext::new(wvr, display))),
|
context: Rc::new(RefCell::new(WayVRContext::new(wvr, display))),
|
||||||
graphics: app.gfx.clone(),
|
graphics: app.gfx.clone(),
|
||||||
image: None,
|
image: None,
|
||||||
@@ -728,27 +750,15 @@ impl OverlayRenderer for WayVRRenderer {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
let set0 = self.pipeline.uniform_sampler(
|
self.pass
|
||||||
0,
|
.update_sampler(0, image.vk_image_view.clone(), self.graphics.texture_filter)?;
|
||||||
image.vk_image_view.clone(),
|
self.buf_alpha.write()?[0] = alpha;
|
||||||
app.gfx.texture_filter,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let set1 = self.pipeline.uniform_buffer_upload(1, vec![alpha])?;
|
|
||||||
|
|
||||||
let pass = self.pipeline.create_pass(
|
|
||||||
tgt.extent_f32(),
|
|
||||||
app.gfx_extras.quad_verts.clone(),
|
|
||||||
0..4,
|
|
||||||
0..1,
|
|
||||||
vec![set0, set1],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mut cmd_buffer = app
|
let mut cmd_buffer = app
|
||||||
.gfx
|
.gfx
|
||||||
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
.create_gfx_command_buffer(CommandBufferUsage::OneTimeSubmit)?;
|
||||||
cmd_buffer.begin_rendering(tgt)?;
|
cmd_buffer.begin_rendering(tgt)?;
|
||||||
cmd_buffer.run_ref(&pass)?;
|
cmd_buffer.run_ref(&self.pass)?;
|
||||||
cmd_buffer.end_rendering()?;
|
cmd_buffer.end_rendering()?;
|
||||||
buf.push(cmd_buffer.build()?);
|
buf.push(cmd_buffer.build()?);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user