atagen

monolith

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

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

824bf02b6e55atagen2026-10-16 09:15 UTC1
use crate::Error;
824bf02b6e55atagen2026-10-16 09:15 UTC2
use crate::device::Shared;
824bf02b6e55atagen2026-10-16 09:15 UTC3
use crate::format::{BYTES_PER_PIXEL, SUPPORTED};
824bf02b6e55atagen2026-10-16 09:15 UTC4
use crate::frame::{Op, VulkanFrame};
824bf02b6e55atagen2026-10-16 09:15 UTC5
use crate::image::{
824bf02b6e55atagen2026-10-16 09:15 UTC6
    ImageInner, Staging, VulkanImage, VulkanMapping, VulkanTarget, VulkanTexture, color_range,
824bf02b6e55atagen2026-10-16 09:15 UTC7
};
824bf02b6e55atagen2026-10-16 09:15 UTC8
use crate::pipeline::Pipelines;
824bf02b6e55atagen2026-10-16 09:15 UTC9
use crate::sync::{FenceInner, VkFence};
824bf02b6e55atagen2026-10-16 09:15 UTC10
use ash::vk;
824bf02b6e55atagen2026-10-16 09:15 UTC11
use gpu_allocator::MemoryLocation;
824bf02b6e55atagen2026-10-16 09:15 UTC12
use smithay::backend::allocator::Fourcc;
824bf02b6e55atagen2026-10-16 09:15 UTC13
use smithay::backend::renderer::sync::SyncPoint;
824bf02b6e55atagen2026-10-16 09:15 UTC14
use smithay::backend::renderer::{
824bf02b6e55atagen2026-10-16 09:15 UTC15
    Bind, ContextId, DebugFlags, ExportMem, ImportMem, Offscreen, Renderer, RendererSuper, Texture,
824bf02b6e55atagen2026-10-16 09:15 UTC16
    TextureFilter,
824bf02b6e55atagen2026-10-16 09:15 UTC17
};
824bf02b6e55atagen2026-10-16 09:15 UTC18
use smithay::utils::{Buffer, Physical, Rectangle, Size, Transform};
824bf02b6e55atagen2026-10-16 09:15 UTC19
use std::fmt;
824bf02b6e55atagen2026-10-16 09:15 UTC20
use std::sync::Arc;
824bf02b6e55atagen2026-10-16 09:15 UTC21
824bf02b6e55atagen2026-10-16 09:15 UTC22
struct Pending {
824bf02b6e55atagen2026-10-16 09:15 UTC23
    fence: Arc<FenceInner>,
824bf02b6e55atagen2026-10-16 09:15 UTC24
    cmd: vk::CommandBuffer,
824bf02b6e55atagen2026-10-16 09:15 UTC25
    _keep: Vec<VulkanTexture>,
824bf02b6e55atagen2026-10-16 09:15 UTC26
}
824bf02b6e55atagen2026-10-16 09:15 UTC27
824bf02b6e55atagen2026-10-16 09:15 UTC28
pub struct VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC29
    pending: Vec<Pending>,
824bf02b6e55atagen2026-10-16 09:15 UTC30
    pipelines: Pipelines,
824bf02b6e55atagen2026-10-16 09:15 UTC31
    pool: vk::CommandPool,
824bf02b6e55atagen2026-10-16 09:15 UTC32
    samplers: [vk::Sampler; 4],
824bf02b6e55atagen2026-10-16 09:15 UTC33
    min_filter: TextureFilter,
824bf02b6e55atagen2026-10-16 09:15 UTC34
    mag_filter: TextureFilter,
824bf02b6e55atagen2026-10-16 09:15 UTC35
    debug: DebugFlags,
824bf02b6e55atagen2026-10-16 09:15 UTC36
    context: ContextId<VulkanTexture>,
824bf02b6e55atagen2026-10-16 09:15 UTC37
    shared: Arc<Shared>,
824bf02b6e55atagen2026-10-16 09:15 UTC38
}
824bf02b6e55atagen2026-10-16 09:15 UTC39
824bf02b6e55atagen2026-10-16 09:15 UTC40
impl fmt::Debug for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC41
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
824bf02b6e55atagen2026-10-16 09:15 UTC42
        f.debug_struct("VulkanRenderer")
824bf02b6e55atagen2026-10-16 09:15 UTC43
            .field("device", &self.shared.device.name)
824bf02b6e55atagen2026-10-16 09:15 UTC44
            .finish()
824bf02b6e55atagen2026-10-16 09:15 UTC45
    }
824bf02b6e55atagen2026-10-16 09:15 UTC46
}
824bf02b6e55atagen2026-10-16 09:15 UTC47
824bf02b6e55atagen2026-10-16 09:15 UTC48
impl VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC49
    pub fn new() -> Result<Self, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC50
        let shared = Arc::new(Shared::new()?);
824bf02b6e55atagen2026-10-16 09:15 UTC51
        let d = &shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC52
        let pool = unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC53
            d.create_command_pool(
824bf02b6e55atagen2026-10-16 09:15 UTC54
                &vk::CommandPoolCreateInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC55
                    .queue_family_index(shared.device.queue_family)
824bf02b6e55atagen2026-10-16 09:15 UTC56
                    .flags(vk::CommandPoolCreateFlags::TRANSIENT),
824bf02b6e55atagen2026-10-16 09:15 UTC57
                None,
824bf02b6e55atagen2026-10-16 09:15 UTC58
            )?
824bf02b6e55atagen2026-10-16 09:15 UTC59
        };
824bf02b6e55atagen2026-10-16 09:15 UTC60
        let filter = |f: TextureFilter| match f {
824bf02b6e55atagen2026-10-16 09:15 UTC61
            TextureFilter::Linear => vk::Filter::LINEAR,
824bf02b6e55atagen2026-10-16 09:15 UTC62
            TextureFilter::Nearest => vk::Filter::NEAREST,
824bf02b6e55atagen2026-10-16 09:15 UTC63
        };
824bf02b6e55atagen2026-10-16 09:15 UTC64
        let mut samplers = [vk::Sampler::null(); 4];
824bf02b6e55atagen2026-10-16 09:15 UTC65
        for (i, s) in samplers.iter_mut().enumerate() {
824bf02b6e55atagen2026-10-16 09:15 UTC66
            let (min, mag) = (sampler_filter(i >> 1), sampler_filter(i & 1));
824bf02b6e55atagen2026-10-16 09:15 UTC67
            *s = unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC68
                d.create_sampler(
824bf02b6e55atagen2026-10-16 09:15 UTC69
                    &vk::SamplerCreateInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC70
                        .min_filter(filter(min))
824bf02b6e55atagen2026-10-16 09:15 UTC71
                        .mag_filter(filter(mag))
824bf02b6e55atagen2026-10-16 09:15 UTC72
                        .address_mode_u(vk::SamplerAddressMode::CLAMP_TO_EDGE)
824bf02b6e55atagen2026-10-16 09:15 UTC73
                        .address_mode_v(vk::SamplerAddressMode::CLAMP_TO_EDGE)
824bf02b6e55atagen2026-10-16 09:15 UTC74
                        .address_mode_w(vk::SamplerAddressMode::CLAMP_TO_EDGE),
824bf02b6e55atagen2026-10-16 09:15 UTC75
                    None,
824bf02b6e55atagen2026-10-16 09:15 UTC76
                )?
824bf02b6e55atagen2026-10-16 09:15 UTC77
            };
824bf02b6e55atagen2026-10-16 09:15 UTC78
        }
824bf02b6e55atagen2026-10-16 09:15 UTC79
        Ok(Self {
824bf02b6e55atagen2026-10-16 09:15 UTC80
            pending: Vec::new(),
824bf02b6e55atagen2026-10-16 09:15 UTC81
            pipelines: Pipelines::new(&shared)?,
824bf02b6e55atagen2026-10-16 09:15 UTC82
            pool,
824bf02b6e55atagen2026-10-16 09:15 UTC83
            samplers,
824bf02b6e55atagen2026-10-16 09:15 UTC84
            min_filter: TextureFilter::Linear,
824bf02b6e55atagen2026-10-16 09:15 UTC85
            mag_filter: TextureFilter::Linear,
824bf02b6e55atagen2026-10-16 09:15 UTC86
            debug: DebugFlags::empty(),
824bf02b6e55atagen2026-10-16 09:15 UTC87
            context: ContextId::new(),
824bf02b6e55atagen2026-10-16 09:15 UTC88
            shared,
824bf02b6e55atagen2026-10-16 09:15 UTC89
        })
824bf02b6e55atagen2026-10-16 09:15 UTC90
    }
824bf02b6e55atagen2026-10-16 09:15 UTC91
824bf02b6e55atagen2026-10-16 09:15 UTC92
    /// Name of the physical device in use.
824bf02b6e55atagen2026-10-16 09:15 UTC93
    pub fn device_name(&self) -> &str {
824bf02b6e55atagen2026-10-16 09:15 UTC94
        &self.shared.device.name
824bf02b6e55atagen2026-10-16 09:15 UTC95
    }
824bf02b6e55atagen2026-10-16 09:15 UTC96
824bf02b6e55atagen2026-10-16 09:15 UTC97
    pub(crate) fn shared(&self) -> &Arc<Shared> {
824bf02b6e55atagen2026-10-16 09:15 UTC98
        &self.shared
824bf02b6e55atagen2026-10-16 09:15 UTC99
    }
824bf02b6e55atagen2026-10-16 09:15 UTC100
824bf02b6e55atagen2026-10-16 09:15 UTC101
    pub(crate) fn context_id_ref(&self) -> &ContextId<VulkanTexture> {
824bf02b6e55atagen2026-10-16 09:15 UTC102
        &self.context
824bf02b6e55atagen2026-10-16 09:15 UTC103
    }
824bf02b6e55atagen2026-10-16 09:15 UTC104
824bf02b6e55atagen2026-10-16 09:15 UTC105
    fn sampler(&self) -> vk::Sampler {
824bf02b6e55atagen2026-10-16 09:15 UTC106
        let idx = |f: TextureFilter| usize::from(f == TextureFilter::Nearest);
824bf02b6e55atagen2026-10-16 09:15 UTC107
        self.samplers[(idx(self.min_filter) << 1) | idx(self.mag_filter)]
824bf02b6e55atagen2026-10-16 09:15 UTC108
    }
824bf02b6e55atagen2026-10-16 09:15 UTC109
824bf02b6e55atagen2026-10-16 09:15 UTC110
    fn reap(&mut self) {
824bf02b6e55atagen2026-10-16 09:15 UTC111
        let d = &self.shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC112
        let pool = self.pool;
824bf02b6e55atagen2026-10-16 09:15 UTC113
        self.pending.retain(|p| {
824bf02b6e55atagen2026-10-16 09:15 UTC114
            if !p.fence.signaled() {
824bf02b6e55atagen2026-10-16 09:15 UTC115
                return true;
824bf02b6e55atagen2026-10-16 09:15 UTC116
            }
824bf02b6e55atagen2026-10-16 09:15 UTC117
            unsafe { d.free_command_buffers(pool, &[p.cmd]) };
824bf02b6e55atagen2026-10-16 09:15 UTC118
            false
824bf02b6e55atagen2026-10-16 09:15 UTC119
        });
824bf02b6e55atagen2026-10-16 09:15 UTC120
    }
824bf02b6e55atagen2026-10-16 09:15 UTC121
824bf02b6e55atagen2026-10-16 09:15 UTC122
    fn begin(&self) -> Result<vk::CommandBuffer, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC123
        let d = &self.shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC124
        let cmd = unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC125
            d.allocate_command_buffers(
824bf02b6e55atagen2026-10-16 09:15 UTC126
                &vk::CommandBufferAllocateInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC127
                    .command_pool(self.pool)
824bf02b6e55atagen2026-10-16 09:15 UTC128
                    .level(vk::CommandBufferLevel::PRIMARY)
824bf02b6e55atagen2026-10-16 09:15 UTC129
                    .command_buffer_count(1),
824bf02b6e55atagen2026-10-16 09:15 UTC130
            )?[0]
824bf02b6e55atagen2026-10-16 09:15 UTC131
        };
824bf02b6e55atagen2026-10-16 09:15 UTC132
        unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC133
            d.begin_command_buffer(
824bf02b6e55atagen2026-10-16 09:15 UTC134
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC135
                &vk::CommandBufferBeginInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC136
                    .flags(vk::CommandBufferUsageFlags::ONE_TIME_SUBMIT),
824bf02b6e55atagen2026-10-16 09:15 UTC137
            )?
824bf02b6e55atagen2026-10-16 09:15 UTC138
        };
824bf02b6e55atagen2026-10-16 09:15 UTC139
        Ok(cmd)
824bf02b6e55atagen2026-10-16 09:15 UTC140
    }
824bf02b6e55atagen2026-10-16 09:15 UTC141
824bf02b6e55atagen2026-10-16 09:15 UTC142
    fn end_and_submit(&self, cmd: vk::CommandBuffer) -> Result<Arc<FenceInner>, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC143
        let d = &self.shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC144
        unsafe { d.end_command_buffer(cmd)? };
824bf02b6e55atagen2026-10-16 09:15 UTC145
        let fence = FenceInner::new(&self.shared)?;
824bf02b6e55atagen2026-10-16 09:15 UTC146
        let cmds = [vk::CommandBufferSubmitInfo::default().command_buffer(cmd)];
824bf02b6e55atagen2026-10-16 09:15 UTC147
        let submit = vk::SubmitInfo2::default().command_buffer_infos(&cmds);
824bf02b6e55atagen2026-10-16 09:15 UTC148
        let queue = self
824bf02b6e55atagen2026-10-16 09:15 UTC149
            .shared
824bf02b6e55atagen2026-10-16 09:15 UTC150
            .device
824bf02b6e55atagen2026-10-16 09:15 UTC151
            .queue
824bf02b6e55atagen2026-10-16 09:15 UTC152
            .lock()
824bf02b6e55atagen2026-10-16 09:15 UTC153
            .unwrap_or_else(|e| e.into_inner());
824bf02b6e55atagen2026-10-16 09:15 UTC154
        unsafe { d.queue_submit2(*queue, &[submit], fence.fence)? };
824bf02b6e55atagen2026-10-16 09:15 UTC155
        Ok(fence)
824bf02b6e55atagen2026-10-16 09:15 UTC156
    }
824bf02b6e55atagen2026-10-16 09:15 UTC157
824bf02b6e55atagen2026-10-16 09:15 UTC158
    /// Records, submits and waits for a short command buffer.
824bf02b6e55atagen2026-10-16 09:15 UTC159
    fn one_shot(
824bf02b6e55atagen2026-10-16 09:15 UTC160
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC161
        record: impl FnOnce(&ash::Device, vk::CommandBuffer),
824bf02b6e55atagen2026-10-16 09:15 UTC162
    ) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC163
        let cmd = self.begin()?;
824bf02b6e55atagen2026-10-16 09:15 UTC164
        record(&self.shared.device.device, cmd);
824bf02b6e55atagen2026-10-16 09:15 UTC165
        let fence = self.end_and_submit(cmd)?;
824bf02b6e55atagen2026-10-16 09:15 UTC166
        let res = fence.wait();
824bf02b6e55atagen2026-10-16 09:15 UTC167
        unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC168
            self.shared
824bf02b6e55atagen2026-10-16 09:15 UTC169
                .device
824bf02b6e55atagen2026-10-16 09:15 UTC170
                .device
824bf02b6e55atagen2026-10-16 09:15 UTC171
                .free_command_buffers(self.pool, &[cmd])
824bf02b6e55atagen2026-10-16 09:15 UTC172
        };
824bf02b6e55atagen2026-10-16 09:15 UTC173
        Ok(res?)
824bf02b6e55atagen2026-10-16 09:15 UTC174
    }
824bf02b6e55atagen2026-10-16 09:15 UTC175
824bf02b6e55atagen2026-10-16 09:15 UTC176
    pub(crate) fn submit(
824bf02b6e55atagen2026-10-16 09:15 UTC177
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC178
        target: &mut VulkanTarget<'_>,
824bf02b6e55atagen2026-10-16 09:15 UTC179
        ops: Vec<Op>,
824bf02b6e55atagen2026-10-16 09:15 UTC180
    ) -> Result<SyncPoint, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC181
        self.reap();
824bf02b6e55atagen2026-10-16 09:15 UTC182
        let image = target.0.0.clone();
824bf02b6e55atagen2026-10-16 09:15 UTC183
        let mut keep = vec![VulkanTexture(image.clone())];
824bf02b6e55atagen2026-10-16 09:15 UTC184
        let mut transitions = Vec::new();
824bf02b6e55atagen2026-10-16 09:15 UTC185
        for op in &ops {
824bf02b6e55atagen2026-10-16 09:15 UTC186
            if let Op::Draw {
824bf02b6e55atagen2026-10-16 09:15 UTC187
                texture: Some(t), ..
824bf02b6e55atagen2026-10-16 09:15 UTC188
            } = op
824bf02b6e55atagen2026-10-16 09:15 UTC189
            {
824bf02b6e55atagen2026-10-16 09:15 UTC190
                if t.0.layout() != vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL {
824bf02b6e55atagen2026-10-16 09:15 UTC191
                    transitions.push(t.clone());
824bf02b6e55atagen2026-10-16 09:15 UTC192
                }
824bf02b6e55atagen2026-10-16 09:15 UTC193
                keep.push(t.clone());
824bf02b6e55atagen2026-10-16 09:15 UTC194
            }
824bf02b6e55atagen2026-10-16 09:15 UTC195
        }
824bf02b6e55atagen2026-10-16 09:15 UTC196
        let mut pipelines = Vec::with_capacity(ops.len());
824bf02b6e55atagen2026-10-16 09:15 UTC197
        for op in &ops {
824bf02b6e55atagen2026-10-16 09:15 UTC198
            pipelines.push(match op {
824bf02b6e55atagen2026-10-16 09:15 UTC199
                Op::Draw { kind, .. } => Some(self.pipelines.get(image.format, *kind)?),
824bf02b6e55atagen2026-10-16 09:15 UTC200
                Op::Clear { .. } => None,
824bf02b6e55atagen2026-10-16 09:15 UTC201
            });
824bf02b6e55atagen2026-10-16 09:15 UTC202
        }
824bf02b6e55atagen2026-10-16 09:15 UTC203
        let cmd = self.begin()?;
824bf02b6e55atagen2026-10-16 09:15 UTC204
        let d = &self.shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC205
        let push = &self.shared.device.push_descriptor;
824bf02b6e55atagen2026-10-16 09:15 UTC206
        let (w, h) = (image.width, image.height);
824bf02b6e55atagen2026-10-16 09:15 UTC207
        let sampler = self.sampler();
824bf02b6e55atagen2026-10-16 09:15 UTC208
        unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC209
            for t in &transitions {
824bf02b6e55atagen2026-10-16 09:15 UTC210
                barrier(
824bf02b6e55atagen2026-10-16 09:15 UTC211
                    d,
824bf02b6e55atagen2026-10-16 09:15 UTC212
                    cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC213
                    t.0.image,
824bf02b6e55atagen2026-10-16 09:15 UTC214
                    t.0.layout(),
824bf02b6e55atagen2026-10-16 09:15 UTC215
                    vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC216
                );
824bf02b6e55atagen2026-10-16 09:15 UTC217
                t.0.set_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC218
            }
824bf02b6e55atagen2026-10-16 09:15 UTC219
            barrier(
824bf02b6e55atagen2026-10-16 09:15 UTC220
                d,
824bf02b6e55atagen2026-10-16 09:15 UTC221
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC222
                image.image,
824bf02b6e55atagen2026-10-16 09:15 UTC223
                image.layout(),
824bf02b6e55atagen2026-10-16 09:15 UTC224
                vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC225
            );
824bf02b6e55atagen2026-10-16 09:15 UTC226
            let attachments = [vk::RenderingAttachmentInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC227
                .image_view(image.view)
824bf02b6e55atagen2026-10-16 09:15 UTC228
                .image_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL)
824bf02b6e55atagen2026-10-16 09:15 UTC229
                .load_op(vk::AttachmentLoadOp::LOAD)
824bf02b6e55atagen2026-10-16 09:15 UTC230
                .store_op(vk::AttachmentStoreOp::STORE)];
824bf02b6e55atagen2026-10-16 09:15 UTC231
            let area = vk::Rect2D {
824bf02b6e55atagen2026-10-16 09:15 UTC232
                offset: vk::Offset2D::default(),
824bf02b6e55atagen2026-10-16 09:15 UTC233
                extent: vk::Extent2D {
824bf02b6e55atagen2026-10-16 09:15 UTC234
                    width: w,
824bf02b6e55atagen2026-10-16 09:15 UTC235
                    height: h,
824bf02b6e55atagen2026-10-16 09:15 UTC236
                },
824bf02b6e55atagen2026-10-16 09:15 UTC237
            };
824bf02b6e55atagen2026-10-16 09:15 UTC238
            d.cmd_begin_rendering(
824bf02b6e55atagen2026-10-16 09:15 UTC239
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC240
                &vk::RenderingInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC241
                    .render_area(area)
824bf02b6e55atagen2026-10-16 09:15 UTC242
                    .layer_count(1)
824bf02b6e55atagen2026-10-16 09:15 UTC243
                    .color_attachments(&attachments),
824bf02b6e55atagen2026-10-16 09:15 UTC244
            );
824bf02b6e55atagen2026-10-16 09:15 UTC245
            d.cmd_set_viewport(
824bf02b6e55atagen2026-10-16 09:15 UTC246
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC247
                0,
824bf02b6e55atagen2026-10-16 09:15 UTC248
                &[vk::Viewport {
824bf02b6e55atagen2026-10-16 09:15 UTC249
                    x: 0.0,
824bf02b6e55atagen2026-10-16 09:15 UTC250
                    y: 0.0,
824bf02b6e55atagen2026-10-16 09:15 UTC251
                    width: w as f32,
824bf02b6e55atagen2026-10-16 09:15 UTC252
                    height: h as f32,
824bf02b6e55atagen2026-10-16 09:15 UTC253
                    min_depth: 0.0,
824bf02b6e55atagen2026-10-16 09:15 UTC254
                    max_depth: 1.0,
824bf02b6e55atagen2026-10-16 09:15 UTC255
                }],
824bf02b6e55atagen2026-10-16 09:15 UTC256
            );
824bf02b6e55atagen2026-10-16 09:15 UTC257
            let mut bound = vk::Pipeline::null();
824bf02b6e55atagen2026-10-16 09:15 UTC258
            for (op, pipeline) in ops.iter().zip(pipelines) {
824bf02b6e55atagen2026-10-16 09:15 UTC259
                match op {
824bf02b6e55atagen2026-10-16 09:15 UTC260
                    Op::Clear { color, rects } => {
824bf02b6e55atagen2026-10-16 09:15 UTC261
                        let clear = [vk::ClearAttachment {
824bf02b6e55atagen2026-10-16 09:15 UTC262
                            aspect_mask: vk::ImageAspectFlags::COLOR,
824bf02b6e55atagen2026-10-16 09:15 UTC263
                            color_attachment: 0,
824bf02b6e55atagen2026-10-16 09:15 UTC264
                            clear_value: vk::ClearValue {
824bf02b6e55atagen2026-10-16 09:15 UTC265
                                color: vk::ClearColorValue { float32: *color },
824bf02b6e55atagen2026-10-16 09:15 UTC266
                            },
824bf02b6e55atagen2026-10-16 09:15 UTC267
                        }];
824bf02b6e55atagen2026-10-16 09:15 UTC268
                        let rects: Vec<_> = rects
824bf02b6e55atagen2026-10-16 09:15 UTC269
                            .iter()
824bf02b6e55atagen2026-10-16 09:15 UTC270
                            .map(|&rect| vk::ClearRect {
824bf02b6e55atagen2026-10-16 09:15 UTC271
                                rect,
824bf02b6e55atagen2026-10-16 09:15 UTC272
                                base_array_layer: 0,
824bf02b6e55atagen2026-10-16 09:15 UTC273
                                layer_count: 1,
824bf02b6e55atagen2026-10-16 09:15 UTC274
                            })
824bf02b6e55atagen2026-10-16 09:15 UTC275
                            .collect();
824bf02b6e55atagen2026-10-16 09:15 UTC276
                        d.cmd_clear_attachments(cmd, &clear, &rects);
824bf02b6e55atagen2026-10-16 09:15 UTC277
                    }
824bf02b6e55atagen2026-10-16 09:15 UTC278
                    Op::Draw {
824bf02b6e55atagen2026-10-16 09:15 UTC279
                        texture,
824bf02b6e55atagen2026-10-16 09:15 UTC280
                        push: constants,
824bf02b6e55atagen2026-10-16 09:15 UTC281
                        scissors,
824bf02b6e55atagen2026-10-16 09:15 UTC282
                        ..
824bf02b6e55atagen2026-10-16 09:15 UTC283
                    } => {
824bf02b6e55atagen2026-10-16 09:15 UTC284
                        let pipeline = pipeline.unwrap_or_default();
824bf02b6e55atagen2026-10-16 09:15 UTC285
                        if pipeline != bound {
824bf02b6e55atagen2026-10-16 09:15 UTC286
                            d.cmd_bind_pipeline(cmd, vk::PipelineBindPoint::GRAPHICS, pipeline);
824bf02b6e55atagen2026-10-16 09:15 UTC287
                            bound = pipeline;
824bf02b6e55atagen2026-10-16 09:15 UTC288
                        }
824bf02b6e55atagen2026-10-16 09:15 UTC289
                        if let Some(t) = texture {
824bf02b6e55atagen2026-10-16 09:15 UTC290
                            let info = [vk::DescriptorImageInfo::default()
824bf02b6e55atagen2026-10-16 09:15 UTC291
                                .image_view(t.0.view)
824bf02b6e55atagen2026-10-16 09:15 UTC292
                                .image_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL)
824bf02b6e55atagen2026-10-16 09:15 UTC293
                                .sampler(sampler)];
824bf02b6e55atagen2026-10-16 09:15 UTC294
                            let write = vk::WriteDescriptorSet::default()
824bf02b6e55atagen2026-10-16 09:15 UTC295
                                .dst_binding(0)
824bf02b6e55atagen2026-10-16 09:15 UTC296
                                .descriptor_type(vk::DescriptorType::COMBINED_IMAGE_SAMPLER)
824bf02b6e55atagen2026-10-16 09:15 UTC297
                                .image_info(&info);
824bf02b6e55atagen2026-10-16 09:15 UTC298
                            push.cmd_push_descriptor_set(
824bf02b6e55atagen2026-10-16 09:15 UTC299
                                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC300
                                vk::PipelineBindPoint::GRAPHICS,
824bf02b6e55atagen2026-10-16 09:15 UTC301
                                self.pipelines.layout,
824bf02b6e55atagen2026-10-16 09:15 UTC302
                                0,
824bf02b6e55atagen2026-10-16 09:15 UTC303
                                &[write],
824bf02b6e55atagen2026-10-16 09:15 UTC304
                            );
824bf02b6e55atagen2026-10-16 09:15 UTC305
                        }
824bf02b6e55atagen2026-10-16 09:15 UTC306
                        d.cmd_push_constants(
824bf02b6e55atagen2026-10-16 09:15 UTC307
                            cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC308
                            self.pipelines.layout,
824bf02b6e55atagen2026-10-16 09:15 UTC309
                            vk::ShaderStageFlags::VERTEX | vk::ShaderStageFlags::FRAGMENT,
824bf02b6e55atagen2026-10-16 09:15 UTC310
                            0,
824bf02b6e55atagen2026-10-16 09:15 UTC311
                            constants.bytes(),
824bf02b6e55atagen2026-10-16 09:15 UTC312
                        );
824bf02b6e55atagen2026-10-16 09:15 UTC313
                        for s in scissors {
824bf02b6e55atagen2026-10-16 09:15 UTC314
                            d.cmd_set_scissor(cmd, 0, &[*s]);
824bf02b6e55atagen2026-10-16 09:15 UTC315
                            d.cmd_draw(cmd, 4, 1, 0, 0);
824bf02b6e55atagen2026-10-16 09:15 UTC316
                        }
824bf02b6e55atagen2026-10-16 09:15 UTC317
                    }
824bf02b6e55atagen2026-10-16 09:15 UTC318
                }
824bf02b6e55atagen2026-10-16 09:15 UTC319
            }
824bf02b6e55atagen2026-10-16 09:15 UTC320
            d.cmd_end_rendering(cmd);
824bf02b6e55atagen2026-10-16 09:15 UTC321
        }
824bf02b6e55atagen2026-10-16 09:15 UTC322
        image.set_layout(vk::ImageLayout::COLOR_ATTACHMENT_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC323
        let fence = self.end_and_submit(cmd)?;
824bf02b6e55atagen2026-10-16 09:15 UTC324
        self.pending.push(Pending {
824bf02b6e55atagen2026-10-16 09:15 UTC325
            fence: fence.clone(),
824bf02b6e55atagen2026-10-16 09:15 UTC326
            cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC327
            _keep: keep,
824bf02b6e55atagen2026-10-16 09:15 UTC328
        });
824bf02b6e55atagen2026-10-16 09:15 UTC329
        Ok(SyncPoint::from(VkFence(fence)))
824bf02b6e55atagen2026-10-16 09:15 UTC330
    }
824bf02b6e55atagen2026-10-16 09:15 UTC331
824bf02b6e55atagen2026-10-16 09:15 UTC332
    fn upload(
824bf02b6e55atagen2026-10-16 09:15 UTC333
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC334
        image: &Arc<ImageInner>,
824bf02b6e55atagen2026-10-16 09:15 UTC335
        data: &[u8],
824bf02b6e55atagen2026-10-16 09:15 UTC336
        region: Rectangle<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC337
        flipped: bool,
824bf02b6e55atagen2026-10-16 09:15 UTC338
    ) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC339
        let width = image.width as usize;
824bf02b6e55atagen2026-10-16 09:15 UTC340
        let needed = width * image.height as usize * BYTES_PER_PIXEL;
824bf02b6e55atagen2026-10-16 09:15 UTC341
        if data.len() < needed {
824bf02b6e55atagen2026-10-16 09:15 UTC342
            return Err(Error::BufferTooSmall {
824bf02b6e55atagen2026-10-16 09:15 UTC343
                needed,
824bf02b6e55atagen2026-10-16 09:15 UTC344
                got: data.len(),
824bf02b6e55atagen2026-10-16 09:15 UTC345
            });
824bf02b6e55atagen2026-10-16 09:15 UTC346
        }
824bf02b6e55atagen2026-10-16 09:15 UTC347
        let mut staging = Staging::new(
824bf02b6e55atagen2026-10-16 09:15 UTC348
            &self.shared,
824bf02b6e55atagen2026-10-16 09:15 UTC349
            needed,
824bf02b6e55atagen2026-10-16 09:15 UTC350
            vk::BufferUsageFlags::TRANSFER_SRC,
824bf02b6e55atagen2026-10-16 09:15 UTC351
            MemoryLocation::CpuToGpu,
824bf02b6e55atagen2026-10-16 09:15 UTC352
        )?;
824bf02b6e55atagen2026-10-16 09:15 UTC353
        let row = width * BYTES_PER_PIXEL;
824bf02b6e55atagen2026-10-16 09:15 UTC354
        let rows = image.height as usize;
824bf02b6e55atagen2026-10-16 09:15 UTC355
        let dst = staging.bytes_mut();
824bf02b6e55atagen2026-10-16 09:15 UTC356
        for y in 0..rows {
824bf02b6e55atagen2026-10-16 09:15 UTC357
            let from = if flipped { rows - 1 - y } else { y };
824bf02b6e55atagen2026-10-16 09:15 UTC358
            dst[y * row..(y + 1) * row].copy_from_slice(&data[from * row..(from + 1) * row]);
824bf02b6e55atagen2026-10-16 09:15 UTC359
        }
824bf02b6e55atagen2026-10-16 09:15 UTC360
        let old = image.layout();
824bf02b6e55atagen2026-10-16 09:15 UTC361
        let copy = vk::BufferImageCopy::default()
824bf02b6e55atagen2026-10-16 09:15 UTC362
            .buffer_offset(
824bf02b6e55atagen2026-10-16 09:15 UTC363
                ((region.loc.y as usize * width + region.loc.x as usize) * BYTES_PER_PIXEL) as u64,
824bf02b6e55atagen2026-10-16 09:15 UTC364
            )
824bf02b6e55atagen2026-10-16 09:15 UTC365
            .buffer_row_length(image.width)
824bf02b6e55atagen2026-10-16 09:15 UTC366
            .image_subresource(
824bf02b6e55atagen2026-10-16 09:15 UTC367
                vk::ImageSubresourceLayers::default()
824bf02b6e55atagen2026-10-16 09:15 UTC368
                    .aspect_mask(vk::ImageAspectFlags::COLOR)
824bf02b6e55atagen2026-10-16 09:15 UTC369
                    .layer_count(1),
824bf02b6e55atagen2026-10-16 09:15 UTC370
            )
824bf02b6e55atagen2026-10-16 09:15 UTC371
            .image_offset(vk::Offset3D {
824bf02b6e55atagen2026-10-16 09:15 UTC372
                x: region.loc.x,
824bf02b6e55atagen2026-10-16 09:15 UTC373
                y: region.loc.y,
824bf02b6e55atagen2026-10-16 09:15 UTC374
                z: 0,
824bf02b6e55atagen2026-10-16 09:15 UTC375
            })
824bf02b6e55atagen2026-10-16 09:15 UTC376
            .image_extent(vk::Extent3D {
824bf02b6e55atagen2026-10-16 09:15 UTC377
                width: region.size.w as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC378
                height: region.size.h as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC379
                depth: 1,
824bf02b6e55atagen2026-10-16 09:15 UTC380
            });
824bf02b6e55atagen2026-10-16 09:15 UTC381
        let (img, buffer) = (image.image, staging.buffer);
824bf02b6e55atagen2026-10-16 09:15 UTC382
        self.one_shot(|d, cmd| unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC383
            barrier(d, cmd, img, old, vk::ImageLayout::TRANSFER_DST_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC384
            d.cmd_copy_buffer_to_image(
824bf02b6e55atagen2026-10-16 09:15 UTC385
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC386
                buffer,
824bf02b6e55atagen2026-10-16 09:15 UTC387
                img,
824bf02b6e55atagen2026-10-16 09:15 UTC388
                vk::ImageLayout::TRANSFER_DST_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC389
                &[copy],
824bf02b6e55atagen2026-10-16 09:15 UTC390
            );
824bf02b6e55atagen2026-10-16 09:15 UTC391
            barrier(
824bf02b6e55atagen2026-10-16 09:15 UTC392
                d,
824bf02b6e55atagen2026-10-16 09:15 UTC393
                cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC394
                img,
824bf02b6e55atagen2026-10-16 09:15 UTC395
                vk::ImageLayout::TRANSFER_DST_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC396
                vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC397
            );
824bf02b6e55atagen2026-10-16 09:15 UTC398
        })?;
824bf02b6e55atagen2026-10-16 09:15 UTC399
        image.set_layout(vk::ImageLayout::SHADER_READ_ONLY_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC400
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC401
    }
824bf02b6e55atagen2026-10-16 09:15 UTC402
824bf02b6e55atagen2026-10-16 09:15 UTC403
    fn read_back(
824bf02b6e55atagen2026-10-16 09:15 UTC404
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC405
        image: &Arc<ImageInner>,
824bf02b6e55atagen2026-10-16 09:15 UTC406
        region: Rectangle<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC407
        fourcc: Fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC408
    ) -> Result<VulkanMapping, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC409
        let region = region
824bf02b6e55atagen2026-10-16 09:15 UTC410
            .intersection(Rectangle::from_size(
824bf02b6e55atagen2026-10-16 09:15 UTC411
                (image.width as i32, image.height as i32).into(),
824bf02b6e55atagen2026-10-16 09:15 UTC412
            ))
824bf02b6e55atagen2026-10-16 09:15 UTC413
            .unwrap_or_default();
824bf02b6e55atagen2026-10-16 09:15 UTC414
        let (w, h) = (region.size.w.max(0) as u32, region.size.h.max(0) as u32);
824bf02b6e55atagen2026-10-16 09:15 UTC415
        let swap = needs_swizzle(image.fourcc, fourcc)?;
824bf02b6e55atagen2026-10-16 09:15 UTC416
        let len = (w as usize * h as usize * BYTES_PER_PIXEL).max(BYTES_PER_PIXEL);
824bf02b6e55atagen2026-10-16 09:15 UTC417
        let staging = Staging::new(
824bf02b6e55atagen2026-10-16 09:15 UTC418
            &self.shared,
824bf02b6e55atagen2026-10-16 09:15 UTC419
            len,
824bf02b6e55atagen2026-10-16 09:15 UTC420
            vk::BufferUsageFlags::TRANSFER_DST,
824bf02b6e55atagen2026-10-16 09:15 UTC421
            MemoryLocation::GpuToCpu,
824bf02b6e55atagen2026-10-16 09:15 UTC422
        )?;
824bf02b6e55atagen2026-10-16 09:15 UTC423
        if w > 0 && h > 0 {
824bf02b6e55atagen2026-10-16 09:15 UTC424
            let old = image.layout();
824bf02b6e55atagen2026-10-16 09:15 UTC425
            let copy = vk::BufferImageCopy::default()
824bf02b6e55atagen2026-10-16 09:15 UTC426
                .image_subresource(
824bf02b6e55atagen2026-10-16 09:15 UTC427
                    vk::ImageSubresourceLayers::default()
824bf02b6e55atagen2026-10-16 09:15 UTC428
                        .aspect_mask(vk::ImageAspectFlags::COLOR)
824bf02b6e55atagen2026-10-16 09:15 UTC429
                        .layer_count(1),
824bf02b6e55atagen2026-10-16 09:15 UTC430
                )
824bf02b6e55atagen2026-10-16 09:15 UTC431
                .image_offset(vk::Offset3D {
824bf02b6e55atagen2026-10-16 09:15 UTC432
                    x: region.loc.x,
824bf02b6e55atagen2026-10-16 09:15 UTC433
                    y: region.loc.y,
824bf02b6e55atagen2026-10-16 09:15 UTC434
                    z: 0,
824bf02b6e55atagen2026-10-16 09:15 UTC435
                })
824bf02b6e55atagen2026-10-16 09:15 UTC436
                .image_extent(vk::Extent3D {
824bf02b6e55atagen2026-10-16 09:15 UTC437
                    width: w,
824bf02b6e55atagen2026-10-16 09:15 UTC438
                    height: h,
824bf02b6e55atagen2026-10-16 09:15 UTC439
                    depth: 1,
824bf02b6e55atagen2026-10-16 09:15 UTC440
                });
824bf02b6e55atagen2026-10-16 09:15 UTC441
            let (img, buffer) = (image.image, staging.buffer);
824bf02b6e55atagen2026-10-16 09:15 UTC442
            self.one_shot(|d, cmd| unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC443
                barrier(d, cmd, img, old, vk::ImageLayout::TRANSFER_SRC_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC444
                d.cmd_copy_image_to_buffer(
824bf02b6e55atagen2026-10-16 09:15 UTC445
                    cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC446
                    img,
824bf02b6e55atagen2026-10-16 09:15 UTC447
                    vk::ImageLayout::TRANSFER_SRC_OPTIMAL,
824bf02b6e55atagen2026-10-16 09:15 UTC448
                    buffer,
824bf02b6e55atagen2026-10-16 09:15 UTC449
                    &[copy],
824bf02b6e55atagen2026-10-16 09:15 UTC450
                );
824bf02b6e55atagen2026-10-16 09:15 UTC451
            })?;
824bf02b6e55atagen2026-10-16 09:15 UTC452
            image.set_layout(vk::ImageLayout::TRANSFER_SRC_OPTIMAL);
824bf02b6e55atagen2026-10-16 09:15 UTC453
        }
824bf02b6e55atagen2026-10-16 09:15 UTC454
        let mut data = staging.bytes()[..w as usize * h as usize * BYTES_PER_PIXEL].to_vec();
824bf02b6e55atagen2026-10-16 09:15 UTC455
        if swap {
824bf02b6e55atagen2026-10-16 09:15 UTC456
            for px in data.as_chunks_mut::<BYTES_PER_PIXEL>().0 {
824bf02b6e55atagen2026-10-16 09:15 UTC457
                px.swap(0, 2);
824bf02b6e55atagen2026-10-16 09:15 UTC458
            }
824bf02b6e55atagen2026-10-16 09:15 UTC459
        }
824bf02b6e55atagen2026-10-16 09:15 UTC460
        Ok(VulkanMapping {
824bf02b6e55atagen2026-10-16 09:15 UTC461
            data,
824bf02b6e55atagen2026-10-16 09:15 UTC462
            width: w,
824bf02b6e55atagen2026-10-16 09:15 UTC463
            height: h,
824bf02b6e55atagen2026-10-16 09:15 UTC464
            fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC465
        })
824bf02b6e55atagen2026-10-16 09:15 UTC466
    }
824bf02b6e55atagen2026-10-16 09:15 UTC467
824bf02b6e55atagen2026-10-16 09:15 UTC468
    fn own(&self, image: &Arc<ImageInner>) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC469
        if Arc::ptr_eq(&image.shared, &self.shared) {
824bf02b6e55atagen2026-10-16 09:15 UTC470
            Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC471
        } else {
824bf02b6e55atagen2026-10-16 09:15 UTC472
            Err(Error::ForeignTexture)
824bf02b6e55atagen2026-10-16 09:15 UTC473
        }
824bf02b6e55atagen2026-10-16 09:15 UTC474
    }
824bf02b6e55atagen2026-10-16 09:15 UTC475
}
824bf02b6e55atagen2026-10-16 09:15 UTC476
824bf02b6e55atagen2026-10-16 09:15 UTC477
impl Drop for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC478
    fn drop(&mut self) {
824bf02b6e55atagen2026-10-16 09:15 UTC479
        let d = &self.shared.device.device;
824bf02b6e55atagen2026-10-16 09:15 UTC480
        unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC481
            let _ = d.device_wait_idle();
824bf02b6e55atagen2026-10-16 09:15 UTC482
            for p in self.pending.drain(..) {
824bf02b6e55atagen2026-10-16 09:15 UTC483
                d.free_command_buffers(self.pool, &[p.cmd]);
824bf02b6e55atagen2026-10-16 09:15 UTC484
            }
824bf02b6e55atagen2026-10-16 09:15 UTC485
            for s in self.samplers {
824bf02b6e55atagen2026-10-16 09:15 UTC486
                d.destroy_sampler(s, None);
824bf02b6e55atagen2026-10-16 09:15 UTC487
            }
824bf02b6e55atagen2026-10-16 09:15 UTC488
            d.destroy_command_pool(self.pool, None);
824bf02b6e55atagen2026-10-16 09:15 UTC489
        }
824bf02b6e55atagen2026-10-16 09:15 UTC490
    }
824bf02b6e55atagen2026-10-16 09:15 UTC491
}
824bf02b6e55atagen2026-10-16 09:15 UTC492
824bf02b6e55atagen2026-10-16 09:15 UTC493
fn sampler_filter(bit: usize) -> TextureFilter {
824bf02b6e55atagen2026-10-16 09:15 UTC494
    if bit == 0 {
824bf02b6e55atagen2026-10-16 09:15 UTC495
        TextureFilter::Linear
824bf02b6e55atagen2026-10-16 09:15 UTC496
    } else {
824bf02b6e55atagen2026-10-16 09:15 UTC497
        TextureFilter::Nearest
824bf02b6e55atagen2026-10-16 09:15 UTC498
    }
824bf02b6e55atagen2026-10-16 09:15 UTC499
}
824bf02b6e55atagen2026-10-16 09:15 UTC500
824bf02b6e55atagen2026-10-16 09:15 UTC501
/// A full barrier between all earlier and later work on the image. Coarse,
824bf02b6e55atagen2026-10-16 09:15 UTC502
/// but correct for every transition the renderer makes.
824bf02b6e55atagen2026-10-16 09:15 UTC503
unsafe fn barrier(
824bf02b6e55atagen2026-10-16 09:15 UTC504
    d: &ash::Device,
824bf02b6e55atagen2026-10-16 09:15 UTC505
    cmd: vk::CommandBuffer,
824bf02b6e55atagen2026-10-16 09:15 UTC506
    image: vk::Image,
824bf02b6e55atagen2026-10-16 09:15 UTC507
    old: vk::ImageLayout,
824bf02b6e55atagen2026-10-16 09:15 UTC508
    new: vk::ImageLayout,
824bf02b6e55atagen2026-10-16 09:15 UTC509
) {
824bf02b6e55atagen2026-10-16 09:15 UTC510
    let b = [vk::ImageMemoryBarrier2::default()
824bf02b6e55atagen2026-10-16 09:15 UTC511
        .src_stage_mask(vk::PipelineStageFlags2::ALL_COMMANDS)
824bf02b6e55atagen2026-10-16 09:15 UTC512
        .src_access_mask(vk::AccessFlags2::MEMORY_WRITE)
824bf02b6e55atagen2026-10-16 09:15 UTC513
        .dst_stage_mask(vk::PipelineStageFlags2::ALL_COMMANDS)
824bf02b6e55atagen2026-10-16 09:15 UTC514
        .dst_access_mask(vk::AccessFlags2::MEMORY_READ | vk::AccessFlags2::MEMORY_WRITE)
824bf02b6e55atagen2026-10-16 09:15 UTC515
        .old_layout(old)
824bf02b6e55atagen2026-10-16 09:15 UTC516
        .new_layout(new)
824bf02b6e55atagen2026-10-16 09:15 UTC517
        .image(image)
824bf02b6e55atagen2026-10-16 09:15 UTC518
        .subresource_range(color_range())];
824bf02b6e55atagen2026-10-16 09:15 UTC519
    unsafe {
824bf02b6e55atagen2026-10-16 09:15 UTC520
        d.cmd_pipeline_barrier2(
824bf02b6e55atagen2026-10-16 09:15 UTC521
            cmd,
824bf02b6e55atagen2026-10-16 09:15 UTC522
            &vk::DependencyInfo::default().image_memory_barriers(&b),
824bf02b6e55atagen2026-10-16 09:15 UTC523
        )
824bf02b6e55atagen2026-10-16 09:15 UTC524
    };
824bf02b6e55atagen2026-10-16 09:15 UTC525
}
824bf02b6e55atagen2026-10-16 09:15 UTC526
824bf02b6e55atagen2026-10-16 09:15 UTC527
/// Whether reading `from` as `to` needs red and blue swapped.
824bf02b6e55atagen2026-10-16 09:15 UTC528
fn needs_swizzle(from: Fourcc, to: Fourcc) -> Result<bool, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC529
    let bgr = |f: Fourcc| match f {
824bf02b6e55atagen2026-10-16 09:15 UTC530
        Fourcc::Argb8888 | Fourcc::Xrgb8888 => Ok(true),
824bf02b6e55atagen2026-10-16 09:15 UTC531
        Fourcc::Abgr8888 | Fourcc::Xbgr8888 => Ok(false),
824bf02b6e55atagen2026-10-16 09:15 UTC532
        f => Err(Error::UnsupportedFormat(f)),
824bf02b6e55atagen2026-10-16 09:15 UTC533
    };
824bf02b6e55atagen2026-10-16 09:15 UTC534
    Ok(bgr(from)? != bgr(to)?)
824bf02b6e55atagen2026-10-16 09:15 UTC535
}
824bf02b6e55atagen2026-10-16 09:15 UTC536
824bf02b6e55atagen2026-10-16 09:15 UTC537
impl RendererSuper for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC538
    type Error = Error;
824bf02b6e55atagen2026-10-16 09:15 UTC539
    type TextureId = VulkanTexture;
824bf02b6e55atagen2026-10-16 09:15 UTC540
    type Framebuffer<'buffer> = VulkanTarget<'buffer>;
824bf02b6e55atagen2026-10-16 09:15 UTC541
    type Frame<'frame, 'buffer>
824bf02b6e55atagen2026-10-16 09:15 UTC542
        = VulkanFrame<'frame, 'buffer>
824bf02b6e55atagen2026-10-16 09:15 UTC543
    where
824bf02b6e55atagen2026-10-16 09:15 UTC544
        'buffer: 'frame,
824bf02b6e55atagen2026-10-16 09:15 UTC545
        Self: 'frame;
824bf02b6e55atagen2026-10-16 09:15 UTC546
}
824bf02b6e55atagen2026-10-16 09:15 UTC547
824bf02b6e55atagen2026-10-16 09:15 UTC548
impl Renderer for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC549
    fn context_id(&self) -> ContextId<VulkanTexture> {
824bf02b6e55atagen2026-10-16 09:15 UTC550
        self.context.clone()
824bf02b6e55atagen2026-10-16 09:15 UTC551
    }
824bf02b6e55atagen2026-10-16 09:15 UTC552
824bf02b6e55atagen2026-10-16 09:15 UTC553
    fn downscale_filter(&mut self, filter: TextureFilter) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC554
        self.min_filter = filter;
824bf02b6e55atagen2026-10-16 09:15 UTC555
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC556
    }
824bf02b6e55atagen2026-10-16 09:15 UTC557
824bf02b6e55atagen2026-10-16 09:15 UTC558
    fn upscale_filter(&mut self, filter: TextureFilter) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC559
        self.mag_filter = filter;
824bf02b6e55atagen2026-10-16 09:15 UTC560
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC561
    }
824bf02b6e55atagen2026-10-16 09:15 UTC562
824bf02b6e55atagen2026-10-16 09:15 UTC563
    fn set_debug_flags(&mut self, flags: DebugFlags) {
824bf02b6e55atagen2026-10-16 09:15 UTC564
        self.debug = flags;
824bf02b6e55atagen2026-10-16 09:15 UTC565
    }
824bf02b6e55atagen2026-10-16 09:15 UTC566
824bf02b6e55atagen2026-10-16 09:15 UTC567
    fn debug_flags(&self) -> DebugFlags {
824bf02b6e55atagen2026-10-16 09:15 UTC568
        self.debug
824bf02b6e55atagen2026-10-16 09:15 UTC569
    }
824bf02b6e55atagen2026-10-16 09:15 UTC570
824bf02b6e55atagen2026-10-16 09:15 UTC571
    fn render<'frame, 'buffer>(
824bf02b6e55atagen2026-10-16 09:15 UTC572
        &'frame mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC573
        framebuffer: &'frame mut VulkanTarget<'buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC574
        output_size: Size<i32, Physical>,
824bf02b6e55atagen2026-10-16 09:15 UTC575
        dst_transform: Transform,
824bf02b6e55atagen2026-10-16 09:15 UTC576
    ) -> Result<VulkanFrame<'frame, 'buffer>, Error>
824bf02b6e55atagen2026-10-16 09:15 UTC577
    where
824bf02b6e55atagen2026-10-16 09:15 UTC578
        'buffer: 'frame,
824bf02b6e55atagen2026-10-16 09:15 UTC579
    {
824bf02b6e55atagen2026-10-16 09:15 UTC580
        self.own(&framebuffer.0.0)?;
824bf02b6e55atagen2026-10-16 09:15 UTC581
        self.reap();
824bf02b6e55atagen2026-10-16 09:15 UTC582
        Ok(VulkanFrame::new(
824bf02b6e55atagen2026-10-16 09:15 UTC583
            self,
824bf02b6e55atagen2026-10-16 09:15 UTC584
            framebuffer,
824bf02b6e55atagen2026-10-16 09:15 UTC585
            output_size,
824bf02b6e55atagen2026-10-16 09:15 UTC586
            dst_transform,
824bf02b6e55atagen2026-10-16 09:15 UTC587
        ))
824bf02b6e55atagen2026-10-16 09:15 UTC588
    }
824bf02b6e55atagen2026-10-16 09:15 UTC589
824bf02b6e55atagen2026-10-16 09:15 UTC590
    fn wait(&mut self, sync: &SyncPoint) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC591
        sync.wait().map_err(|_| Error::Interrupted)
824bf02b6e55atagen2026-10-16 09:15 UTC592
    }
824bf02b6e55atagen2026-10-16 09:15 UTC593
824bf02b6e55atagen2026-10-16 09:15 UTC594
    fn cleanup_texture_cache(&mut self) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC595
        self.reap();
824bf02b6e55atagen2026-10-16 09:15 UTC596
        Ok(())
824bf02b6e55atagen2026-10-16 09:15 UTC597
    }
824bf02b6e55atagen2026-10-16 09:15 UTC598
}
824bf02b6e55atagen2026-10-16 09:15 UTC599
824bf02b6e55atagen2026-10-16 09:15 UTC600
impl Bind<VulkanImage> for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC601
    fn bind<'a>(&mut self, target: &'a mut VulkanImage) -> Result<VulkanTarget<'a>, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC602
        self.own(&target.0)?;
824bf02b6e55atagen2026-10-16 09:15 UTC603
        Ok(VulkanTarget(target))
824bf02b6e55atagen2026-10-16 09:15 UTC604
    }
824bf02b6e55atagen2026-10-16 09:15 UTC605
}
824bf02b6e55atagen2026-10-16 09:15 UTC606
824bf02b6e55atagen2026-10-16 09:15 UTC607
impl Offscreen<VulkanImage> for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC608
    fn create_buffer(
824bf02b6e55atagen2026-10-16 09:15 UTC609
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC610
        format: Fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC611
        size: Size<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC612
    ) -> Result<VulkanImage, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC613
        if size.w <= 0 || size.h <= 0 {
824bf02b6e55atagen2026-10-16 09:15 UTC614
            return Err(Error::InvalidSize(size.w, size.h));
824bf02b6e55atagen2026-10-16 09:15 UTC615
        }
824bf02b6e55atagen2026-10-16 09:15 UTC616
        let usage = vk::ImageUsageFlags::COLOR_ATTACHMENT
824bf02b6e55atagen2026-10-16 09:15 UTC617
            | vk::ImageUsageFlags::SAMPLED
824bf02b6e55atagen2026-10-16 09:15 UTC618
            | vk::ImageUsageFlags::TRANSFER_SRC
824bf02b6e55atagen2026-10-16 09:15 UTC619
            | vk::ImageUsageFlags::TRANSFER_DST;
824bf02b6e55atagen2026-10-16 09:15 UTC620
        Ok(VulkanImage(ImageInner::create(
824bf02b6e55atagen2026-10-16 09:15 UTC621
            &self.shared,
824bf02b6e55atagen2026-10-16 09:15 UTC622
            format,
824bf02b6e55atagen2026-10-16 09:15 UTC623
            size.w as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC624
            size.h as u32,
824bf02b6e55atagen2026-10-16 09:15 UTC625
            usage,
824bf02b6e55atagen2026-10-16 09:15 UTC626
        )?))
824bf02b6e55atagen2026-10-16 09:15 UTC627
    }
824bf02b6e55atagen2026-10-16 09:15 UTC628
}
824bf02b6e55atagen2026-10-16 09:15 UTC629
824bf02b6e55atagen2026-10-16 09:15 UTC630
impl ImportMem for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC631
    fn import_memory(
824bf02b6e55atagen2026-10-16 09:15 UTC632
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC633
        data: &[u8],
824bf02b6e55atagen2026-10-16 09:15 UTC634
        format: Fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC635
        size: Size<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC636
        flipped: bool,
824bf02b6e55atagen2026-10-16 09:15 UTC637
    ) -> Result<VulkanTexture, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC638
        if size.w <= 0 || size.h <= 0 {
824bf02b6e55atagen2026-10-16 09:15 UTC639
            return Err(Error::InvalidSize(size.w, size.h));
824bf02b6e55atagen2026-10-16 09:15 UTC640
        }
824bf02b6e55atagen2026-10-16 09:15 UTC641
        let usage = vk::ImageUsageFlags::SAMPLED
824bf02b6e55atagen2026-10-16 09:15 UTC642
            | vk::ImageUsageFlags::TRANSFER_DST
824bf02b6e55atagen2026-10-16 09:15 UTC643
            | vk::ImageUsageFlags::TRANSFER_SRC;
824bf02b6e55atagen2026-10-16 09:15 UTC644
        let image = ImageInner::create(&self.shared, format, size.w as u32, size.h as u32, usage)?;
824bf02b6e55atagen2026-10-16 09:15 UTC645
        self.upload(&image, data, Rectangle::from_size(size), flipped)?;
824bf02b6e55atagen2026-10-16 09:15 UTC646
        Ok(VulkanTexture(image))
824bf02b6e55atagen2026-10-16 09:15 UTC647
    }
824bf02b6e55atagen2026-10-16 09:15 UTC648
824bf02b6e55atagen2026-10-16 09:15 UTC649
    fn update_memory(
824bf02b6e55atagen2026-10-16 09:15 UTC650
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC651
        texture: &VulkanTexture,
824bf02b6e55atagen2026-10-16 09:15 UTC652
        data: &[u8],
824bf02b6e55atagen2026-10-16 09:15 UTC653
        region: Rectangle<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC654
    ) -> Result<(), Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC655
        self.own(&texture.0)?;
824bf02b6e55atagen2026-10-16 09:15 UTC656
        let Some(region) = region.intersection(Rectangle::from_size(texture.size())) else {
824bf02b6e55atagen2026-10-16 09:15 UTC657
            return Ok(());
824bf02b6e55atagen2026-10-16 09:15 UTC658
        };
824bf02b6e55atagen2026-10-16 09:15 UTC659
        self.upload(&texture.0, data, region, false)
824bf02b6e55atagen2026-10-16 09:15 UTC660
    }
824bf02b6e55atagen2026-10-16 09:15 UTC661
824bf02b6e55atagen2026-10-16 09:15 UTC662
    fn mem_formats(&self) -> Box<dyn Iterator<Item = Fourcc>> {
824bf02b6e55atagen2026-10-16 09:15 UTC663
        Box::new(SUPPORTED.into_iter())
824bf02b6e55atagen2026-10-16 09:15 UTC664
    }
824bf02b6e55atagen2026-10-16 09:15 UTC665
}
824bf02b6e55atagen2026-10-16 09:15 UTC666
824bf02b6e55atagen2026-10-16 09:15 UTC667
impl ExportMem for VulkanRenderer {
824bf02b6e55atagen2026-10-16 09:15 UTC668
    type TextureMapping = VulkanMapping;
824bf02b6e55atagen2026-10-16 09:15 UTC669
824bf02b6e55atagen2026-10-16 09:15 UTC670
    fn copy_framebuffer(
824bf02b6e55atagen2026-10-16 09:15 UTC671
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC672
        target: &VulkanTarget<'_>,
824bf02b6e55atagen2026-10-16 09:15 UTC673
        region: Rectangle<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC674
        format: Fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC675
    ) -> Result<VulkanMapping, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC676
        self.own(&target.0.0)?;
824bf02b6e55atagen2026-10-16 09:15 UTC677
        let image = target.0.0.clone();
824bf02b6e55atagen2026-10-16 09:15 UTC678
        self.read_back(&image, region, format)
824bf02b6e55atagen2026-10-16 09:15 UTC679
    }
824bf02b6e55atagen2026-10-16 09:15 UTC680
824bf02b6e55atagen2026-10-16 09:15 UTC681
    fn copy_texture(
824bf02b6e55atagen2026-10-16 09:15 UTC682
        &mut self,
824bf02b6e55atagen2026-10-16 09:15 UTC683
        texture: &VulkanTexture,
824bf02b6e55atagen2026-10-16 09:15 UTC684
        region: Rectangle<i32, Buffer>,
824bf02b6e55atagen2026-10-16 09:15 UTC685
        format: Fourcc,
824bf02b6e55atagen2026-10-16 09:15 UTC686
    ) -> Result<VulkanMapping, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC687
        self.own(&texture.0)?;
824bf02b6e55atagen2026-10-16 09:15 UTC688
        self.read_back(&texture.0, region, format)
824bf02b6e55atagen2026-10-16 09:15 UTC689
    }
824bf02b6e55atagen2026-10-16 09:15 UTC690
824bf02b6e55atagen2026-10-16 09:15 UTC691
    fn can_read_texture(&mut self, _texture: &VulkanTexture) -> Result<bool, Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC692
        Ok(true)
824bf02b6e55atagen2026-10-16 09:15 UTC693
    }
824bf02b6e55atagen2026-10-16 09:15 UTC694
824bf02b6e55atagen2026-10-16 09:15 UTC695
    fn map_texture<'a>(&mut self, mapping: &'a VulkanMapping) -> Result<&'a [u8], Error> {
824bf02b6e55atagen2026-10-16 09:15 UTC696
        Ok(&mapping.data)
824bf02b6e55atagen2026-10-16 09:15 UTC697
    }
824bf02b6e55atagen2026-10-16 09:15 UTC698
}