use bytemuck::{Pod, Zeroable};
use vello_common::tile::Tile;
#[repr(C, align(16))]
#[derive(Debug, Clone, Copy, Pod, Zeroable)]
pub struct GpuConfig {
pub width: u32,
pub height: u32,
pub strip_height: u32,
pub alphas_tex_width_bits: u32,
pub encoded_paints_tex_width_bits: u32,
pub strip_offset_x: i32,
pub strip_offset_y: i32,
pub negate_ndc: u32,
}
const _: () = assert!(
size_of::<GpuConfig>() == 32,
"`GpuConfig` must stay 32 bytes — the shaders' `Config` uniform layout",
);
const _: () = assert!(
align_of::<GpuConfig>() == 16,
"`GpuConfig` must stay 16-byte aligned — uniform-buffer layout rules",
);
impl GpuConfig {
pub const SIZE: u64 = size_of::<Self>() as u64;
#[must_use]
pub fn new(
width: u32,
height: u32,
alphas_tex_width: u32,
encoded_paints_tex_width: u32,
) -> Self {
Self {
width,
height,
strip_height: u32::from(Tile::HEIGHT),
alphas_tex_width_bits: tex_width_bits(alphas_tex_width),
encoded_paints_tex_width_bits: tex_width_bits(encoded_paints_tex_width),
strip_offset_x: 0,
strip_offset_y: 0,
negate_ndc: 0,
}
}
#[must_use]
pub const fn with_strip_offset(mut self, x: i32, y: i32) -> Self {
self.strip_offset_x = x;
self.strip_offset_y = y;
self
}
#[must_use]
pub const fn with_negate_ndc(mut self, negate: bool) -> Self {
self.negate_ndc = negate as u32;
self
}
}
#[must_use]
pub fn tex_width_bits(width: u32) -> u32 {
debug_assert!(
width.is_power_of_two(),
"resource texture width must be a power of two, got {width}",
);
width.trailing_zeros()
}