atagen

monolith

public
Star0
Watch0
5b7cddd2e177149d7bdb4006fcb9b174e08cb3cc
1
ssh://brewery@pls.lobotomise.me:33/atagen/monolith.git

Blame: crates/render-vk/src/frame.rs

824bf02b6e55atagen2026-10-16 09:15 UTC1
use crate::Error;
824bf02b6e55atagen2026-10-16 09:15 UTC2
use crate::image::{VulkanTarget, VulkanTexture};
824bf02b6e55atagen2026-10-16 09:15 UTC3
use crate::pipeline::{Kind, Push};
824bf02b6e55atagen2026-10-16 09:15 UTC4
use crate::renderer::VulkanRenderer;
824bf02b6e55atagen2026-10-16 09:15 UTC5
use crate::transform::{rect_to_framebuffer, texture_uvs, to_framebuffer};
824bf02b6e55atagen2026-10-16 09:15 UTC6
use ash::vk;
824bf02b6e55atagen2026-10-16 09:15 UTC7
use smithay::backend::renderer::sync::SyncPoint;
824bf02b6e55atagen2026-10-16 09:15 UTC8
use smithay::backend::renderer::{Color32F, ContextId, Frame, Texture};
824bf02b6e55atagen2026-10-16 09:15 UTC9
use smithay::utils::{Buffer, Physical, Rectangle, Size, Transform};
824bf02b6e55atagen2026-10-16 09:15 UTC10
use std::sync::Arc;
824bf02b6e55atagen2026-10-16 09:15 UTC11
824bf02b6e55atagen2026-10-16 09:15 UTC12
pub(crate) enum Op {
824bf02b6e55atagen2026-10-16 09:15 UTC13
    Clear {
824bf02b6e55atagen2026-10-16 09:15 UTC14
        color: [f32; 4],
824bf02b6e55atagen2026-10-16 09:15 UTC15
        rects: Vec<vk::Rect2D>,
824bf02b6e55atagen2026-10-16 09:15 UTC16
    },
824bf02b6e55atagen2026-10-16 09:15 UTC17
    Draw {
824bf02b6e55atagen2026-10-16 09:15 UTC18
        kind: Kind,
824bf02b6e55atagen2026-10-16 09:15 UTC19
        texture: Option<VulkanTexture>,
824bf02b6e55atagen2026-10-16 09:15 UTC20
        push: Push,
824bf02b6e55atagen2026-10-16 09:15 UTC21
        scissors: Vec<vk::Rect2D>,
824bf02b6e55atagen2026-10-16 09:15 UTC22
    },
824bf02b6e55atagen2026-10-16 09:15 UTC23
}
824bf02b6e55atagen2026-10-16 09:15 UTC24
824bf02b6e55atagen2026-10-16 09:15 UTC25
/// A frame in progress. Draws are recorded and submitted together by [`Frame::finish`].
824bf02b6e55atagen2026-10-16 09:15 UTC26
pub struct VulkanFrame<'frame, 'buffer> {
824bf02b6e55atagen2026-10-16 09:15 UTC27
    renderer: &'frame mut VulkanRenderer,
824bf02b6e55atagen2026-10-16 09:15 UTC28
    target: &'frame mut VulkanTarget<'buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC29
    output: Size<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC30
    transform: Transform,
824bf02b6e55atagen2026-10-16 09:15 UTC31
    ops: Vec<Op>,
824bf02b6e55atagen2026-10-16 09:15 UTC32
}
824bf02b6e55atagen2026-10-16 09:15 UTC33
824bf02b6e55atagen2026-10-16 09:15 UTC34
impl std::fmt::Debug for VulkanFrame<'_, '_> {
824bf02b6e55atagen2026-10-16 09:15 UTC35
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
824bf02b6e55atagen2026-10-16 09:15 UTC36
        f.debug_struct("VulkanFrame")
824bf02b6e55atagen2026-10-16 09:15 UTC37
            .field("output", &self.output)
824bf02b6e55atagen2026-10-16 09:15 UTC38
            .field("ops", &self.ops.len())
824bf02b6e55atagen2026-10-16 09:15 UTC39
            .finish()
824bf02b6e55atagen2026-10-16 09:15 UTC40
    }
824bf02b6e55atagen2026-10-16 09:15 UTC41
}
824bf02b6e55atagen2026-10-16 09:15 UTC42
824bf02b6e55atagen2026-10-16 09:15 UTC43
impl<'frame, 'buffer> VulkanFrame<'frame, 'buffer> {
824bf02b6e55atagen2026-10-16 09:15 UTC44
    pub(crate) fn new(
824bf02b6e55atagen2026-10-16 09:15 UTC45
        renderer: &'frame mut VulkanRenderer,
824bf02b6e55atagen2026-10-16 09:15 UTC46
        target: &'frame mut VulkanTarget<'buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC47
        output: Size<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC48
        transform: Transform,
824bf02b6e55atagen2026-10-16 09:15 UTC49
    ) -> Self {
824bf02b6e55atagen2026-10-16 09:15 UTC50
        Self {
824bf02b6e55atagen2026-10-16 09:15 UTC51
            renderer,
824bf02b6e55atagen2026-10-16 09:15 UTC52
            target,
824bf02b6e55atagen2026-10-16 09:15 UTC53
            output,
824bf02b6e55atagen2026-10-16 09:15 UTC54
            transform,
824bf02b6e55atagen2026-10-16 09:15 UTC55
            ops: Vec::new(),
824bf02b6e55atagen2026-10-16 09:15 UTC56
        }
824bf02b6e55atagen2026-10-16 09:15 UTC57
    }
824bf02b6e55atagen2026-10-16 09:15 UTC58
824bf02b6e55atagen2026-10-16 09:15 UTC59
    fn fb_size(&self) -> Size<i32, Physical> {
824bf02b6e55atagen2026-10-16 09:15 UTC60
        (self.target.width() as i32, self.target.height() as i32).into()
824bf02b6e55atagen2026-10-16 09:15 UTC61
    }
824bf02b6e55atagen2026-10-16 09:15 UTC62
824bf02b6e55atagen2026-10-16 09:15 UTC63
    fn fb_rect(&self, r: Rectangle<i32, Physical>) -> Option<vk::Rect2D> {
824bf02b6e55atagen2026-10-16 09:15 UTC64
        let r = rect_to_framebuffer(r, self.output, self.transform)
824bf02b6e55atagen2026-10-16 09:15 UTC65
            .intersection(Rectangle::from_size(self.fb_size()))?;
824bf02b6e55atagen2026-10-16 09:15 UTC66
        Some(vk::Rect2D {
824bf02b6e55atagen2026-10-16 09:15 UTC67
            offset: vk::Offset2D {
824bf02b6e55atagen2026-10-16 09:15 UTC68
                x: r.loc.x,
824bf02b6e55atagen2026-10-16 09:15 UTC69
                y: r.loc.y,
824bf02b6e55atagen2026-10-16 09:15 UTC70
            },
824bf02b6e55atagen2026-10-16 09:15 UTC71
            extent: vk::Extent2D {
824bf02b6e55atagen2026-10-16 09:15 UTC72
                width: r.size.w as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC73
                height: r.size.h as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC74
            },
824bf02b6e55atagen2026-10-16 09:15 UTC75
        })
824bf02b6e55atagen2026-10-16 09:15 UTC76
    }
824bf02b6e55atagen2026-10-16 09:15 UTC77
824bf02b6e55atagen2026-10-16 09:15 UTC78
    fn scissors(
824bf02b6e55atagen2026-10-16 09:15 UTC79
        &self,
824bf02b6e55atagen2026-10-16 09:15 UTC80
        dst: Rectangle<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC81
        damage: &[Rectangle<i32, Physical>],
824bf02b6e55atagen2026-10-16 09:15 UTC82
    ) -> Vec<vk::Rect2D> {
824bf02b6e55atagen2026-10-16 09:15 UTC83
        damage
824bf02b6e55atagen2026-10-16 09:15 UTC84
            .iter()
824bf02b6e55atagen2026-10-16 09:15 UTC85
            .filter_map(|d| d.intersection(Rectangle::from_size(dst.size)))
824bf02b6e55atagen2026-10-16 09:15 UTC86
            .filter_map(|mut d| {
824bf02b6e55atagen2026-10-16 09:15 UTC87
                d.loc += dst.loc;
824bf02b6e55atagen2026-10-16 09:15 UTC88
                self.fb_rect(d)
824bf02b6e55atagen2026-10-16 09:15 UTC89
            })
824bf02b6e55atagen2026-10-16 09:15 UTC90
            .collect()
824bf02b6e55atagen2026-10-16 09:15 UTC91
    }
824bf02b6e55atagen2026-10-16 09:15 UTC92
824bf02b6e55atagen2026-10-16 09:15 UTC93
    fn ndc(&self, r: Rectangle<i32, Physical>) -> [f32; 4] {
824bf02b6e55atagen2026-10-16 09:15 UTC94
        let fb = self.fb_size();
824bf02b6e55atagen2026-10-16 09:15 UTC95
        let (w, h) = (fb.w as f32, fb.h as f32);
824bf02b6e55atagen2026-10-16 09:15 UTC96
        [
824bf02b6e55atagen2026-10-16 09:15 UTC97
            r.loc.x as f32 / w * 2.0 - 1.0,
824bf02b6e55atagen2026-10-16 09:15 UTC98
            r.loc.y as f32 / h * 2.0 - 1.0,
824bf02b6e55atagen2026-10-16 09:15 UTC99
            r.size.w as f32 / w * 2.0,
824bf02b6e55atagen2026-10-16 09:15 UTC100
            r.size.h as f32 / h * 2.0,
824bf02b6e55atagen2026-10-16 09:15 UTC101
        ]
824bf02b6e55atagen2026-10-16 09:15 UTC102
    }
824bf02b6e55atagen2026-10-16 09:15 UTC103
}
824bf02b6e55atagen2026-10-16 09:15 UTC104
824bf02b6e55atagen2026-10-16 09:15 UTC105
impl Frame for VulkanFrame<'_, '_> {
824bf02b6e55atagen2026-10-16 09:15 UTC106
    type Error = Error;
824bf02b6e55atagen2026-10-16 09:15 UTC107
    type TextureId = VulkanTexture;
824bf02b6e55atagen2026-10-16 09:15 UTC108
824bf02b6e55atagen2026-10-16 09:15 UTC109
    fn context_id(&self) -> ContextId<VulkanTexture> {
824bf02b6e55atagen2026-10-16 09:15 UTC110
        self.renderer.context_id_ref().clone()
824bf02b6e55atagen2026-10-16 09:15 UTC111
    }
824bf02b6e55atagen2026-10-16 09:15 UTC112
824bf02b6e55atagen2026-10-16 09:15 UTC113
    fn clear(&mut self, color: Color32F, at: &[Rectangle<i32, Physical>]) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC114
        let rects: Vec<_> = at.iter().filter_map(|r| self.fb_rect(*r)).collect();
824bf02b6e55atagen2026-10-16 09:15 UTC115
        if !rects.is_empty() {
824bf02b6e55atagen2026-10-16 09:15 UTC116
            self.ops.push(Op::Clear {
824bf02b6e55atagen2026-10-16 09:15 UTC117
                color: color.components(),
824bf02b6e55atagen2026-10-16 09:15 UTC118
                rects,
824bf02b6e55atagen2026-10-16 09:15 UTC119
            });
824bf02b6e55atagen2026-10-16 09:15 UTC120
        }
824bf02b6e55atagen2026-10-16 09:15 UTC121
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC122
    }
824bf02b6e55atagen2026-10-16 09:15 UTC123
824bf02b6e55atagen2026-10-16 09:15 UTC124
    fn draw_solid(
824bf02b6e55atagen2026-10-16 09:15 UTC125
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC126
        dst: Rectangle<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC127
        damage: &[Rectangle<i32, Physical>],
824bf02b6e55atagen2026-10-16 09:15 UTC128
        color: Color32F,
824bf02b6e55atagen2026-10-16 09:15 UTC129
    ) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC130
        let scissors = self.scissors(dst, damage);
824bf02b6e55atagen2026-10-16 09:15 UTC131
        if scissors.is_empty() {
824bf02b6e55atagen2026-10-16 09:15 UTC132
            return Ok(());
824bf02b6e55atagen2026-10-16 09:15 UTC133
        }
824bf02b6e55atagen2026-10-16 09:15 UTC134
        let (fb, _) = to_framebuffer(dst, [[0.0; 2]; 4], self.output, self.transform);
824bf02b6e55atagen2026-10-16 09:15 UTC135
        let push = Push {
824bf02b6e55atagen2026-10-16 09:15 UTC136
            dst: self.ndc(fb),
824bf02b6e55atagen2026-10-16 09:15 UTC137
            uv: [[0.0; 2]; 4],
824bf02b6e55atagen2026-10-16 09:15 UTC138
            color: color.components(),
824bf02b6e55atagen2026-10-16 09:15 UTC139
        };
824bf02b6e55atagen2026-10-16 09:15 UTC140
        self.ops.push(Op::Draw {
824bf02b6e55atagen2026-10-16 09:15 UTC141
            kind: Kind::Solid,
824bf02b6e55atagen2026-10-16 09:15 UTC142
            texture: None,
824bf02b6e55atagen2026-10-16 09:15 UTC143
            push,
824bf02b6e55atagen2026-10-16 09:15 UTC144
            scissors,
824bf02b6e55atagen2026-10-16 09:15 UTC145
        });
824bf02b6e55atagen2026-10-16 09:15 UTC146
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC147
    }
824bf02b6e55atagen2026-10-16 09:15 UTC148
824bf02b6e55atagen2026-10-16 09:15 UTC149
    fn render_texture_from_to(
824bf02b6e55atagen2026-10-16 09:15 UTC150
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC151
        texture: &VulkanTexture,
824bf02b6e55atagen2026-10-16 09:15 UTC152
        src: Rectangle<f64, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC153
        dst: Rectangle<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC154
        damage: &[Rectangle<i32, Physical>],
824bf02b6e55atagen2026-10-16 09:15 UTC155
        _opaque_regions: &[Rectangle<i32, Physical>],
824bf02b6e55atagen2026-10-16 09:15 UTC156
        src_transform: Transform,
824bf02b6e55atagen2026-10-16 09:15 UTC157
        alpha: f32,
824bf02b6e55atagen2026-10-16 09:15 UTC158
    ) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC159
        if !Arc::ptr_eq(&texture.0.shared, self.renderer.shared()) {
824bf02b6e55atagen2026-10-16 09:15 UTC160
            return Err(Error::ForeignTexture);
824bf02b6e55atagen2026-10-16 09:15 UTC161
        }
7de49c2aa70batagen2026-10-16 09:27 UTC162
        if dst.size.w <= 0 || dst.size.h <= 0 || Arc::ptr_eq(&texture.0, &self.target.0) {
824bf02b6e55atagen2026-10-16 09:15 UTC163
            return Ok(());
824bf02b6e55atagen2026-10-16 09:15 UTC164
        }
824bf02b6e55atagen2026-10-16 09:15 UTC165
        let scissors = self.scissors(dst, damage);
824bf02b6e55atagen2026-10-16 09:15 UTC166
        if scissors.is_empty() {
824bf02b6e55atagen2026-10-16 09:15 UTC167
            return Ok(());
824bf02b6e55atagen2026-10-16 09:15 UTC168
        }
824bf02b6e55atagen2026-10-16 09:15 UTC169
        let uvs = texture_uvs(src, dst.size, texture.size(), src_transform);
824bf02b6e55atagen2026-10-16 09:15 UTC170
        let (fb, uv) = to_framebuffer(dst, uvs, self.output, self.transform);
824bf02b6e55atagen2026-10-16 09:15 UTC171
        let push = Push {
824bf02b6e55atagen2026-10-16 09:15 UTC172
            dst: self.ndc(fb),
824bf02b6e55atagen2026-10-16 09:15 UTC173
            uv,
824bf02b6e55atagen2026-10-16 09:15 UTC174
            color: [1.0, 1.0, 1.0, alpha],
824bf02b6e55atagen2026-10-16 09:15 UTC175
        };
824bf02b6e55atagen2026-10-16 09:15 UTC176
        self.ops.push(Op::Draw {
824bf02b6e55atagen2026-10-16 09:15 UTC177
            kind: Kind::Texture,
824bf02b6e55atagen2026-10-16 09:15 UTC178
            texture: Some(texture.clone()),
824bf02b6e55atagen2026-10-16 09:15 UTC179
            push,
824bf02b6e55atagen2026-10-16 09:15 UTC180
            scissors,
824bf02b6e55atagen2026-10-16 09:15 UTC181
        });
824bf02b6e55atagen2026-10-16 09:15 UTC182
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC183
    }
824bf02b6e55atagen2026-10-16 09:15 UTC184
824bf02b6e55atagen2026-10-16 09:15 UTC185
    fn transformation(&self) -> Transform {
824bf02b6e55atagen2026-10-16 09:15 UTC186
        self.transform
824bf02b6e55atagen2026-10-16 09:15 UTC187
    }
824bf02b6e55atagen2026-10-16 09:15 UTC188
824bf02b6e55atagen2026-10-16 09:15 UTC189
    fn output_size(&self) -> Size<i32, Physical> {
824bf02b6e55atagen2026-10-16 09:15 UTC190
        self.output
824bf02b6e55atagen2026-10-16 09:15 UTC191
    }
824bf02b6e55atagen2026-10-16 09:15 UTC192
824bf02b6e55atagen2026-10-16 09:15 UTC193
    fn wait(&mut self, sync: &SyncPoint) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC194
        sync.wait().map_err(|_| Error::Interrupted)
824bf02b6e55atagen2026-10-16 09:15 UTC195
    }
824bf02b6e55atagen2026-10-16 09:15 UTC196
824bf02b6e55atagen2026-10-16 09:15 UTC197
    fn finish(mut self) -> Result<SyncPoint, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC198
        let ops = std::mem::take(&mut self.ops);
824bf02b6e55atagen2026-10-16 09:15 UTC199
        self.renderer.submit(self.target, ops)
824bf02b6e55atagen2026-10-16 09:15 UTC200
    }
824bf02b6e55atagen2026-10-16 09:15 UTC201
}