blob: a18c2b59fdf23f99d8b7ed18023eeb2e86a71692 [file] [log] [blame] [edit]
// Copyright 2023 The Vello authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
use vello_encoding::{BumpAllocators, ConfigUniform, DrawTag, Path, Tile};
use crate::cpu_dispatch::CpuBinding;
const TILE_WIDTH: usize = 16;
const TILE_HEIGHT: usize = 16;
const SX: f32 = 1.0 / (TILE_WIDTH as f32);
const SY: f32 = 1.0 / (TILE_HEIGHT as f32);
fn tile_alloc_main(
config: &ConfigUniform,
scene: &[u32],
draw_bboxes: &[[f32; 4]],
bump: &mut BumpAllocators,
paths: &mut [Path],
tiles: &mut [Tile],
) {
let drawtag_base = config.layout.draw_tag_base;
let width_in_tiles = config.width_in_tiles as i32;
let height_in_tiles = config.height_in_tiles as i32;
for drawobj_ix in 0..config.layout.n_draw_objects {
let drawtag = DrawTag(scene[(drawtag_base + drawobj_ix) as usize]);
let mut x0 = 0;
let mut y0 = 0;
let mut x1 = 0;
let mut y1 = 0;
if drawtag != DrawTag::NOP && drawtag != DrawTag::END_CLIP {
let bbox = draw_bboxes[drawobj_ix as usize];
x0 = (bbox[0] * SX).floor() as i32;
y0 = (bbox[1] * SY).floor() as i32;
x1 = (bbox[2] * SX).ceil() as i32;
y1 = (bbox[3] * SY).ceil() as i32;
}
let ux0 = x0.clamp(0, width_in_tiles) as u32;
let uy0 = y0.clamp(0, height_in_tiles) as u32;
let ux1 = x1.clamp(0, width_in_tiles) as u32;
let uy1 = y1.clamp(0, height_in_tiles) as u32;
let tile_count = (ux1 - ux0) * (uy1 - uy0);
let offset = bump.tile;
bump.tile += tile_count;
// We construct it this way because padding is private.
let mut path = Path::default();
path.bbox = [ux0, uy0, ux1, uy1];
path.tiles = offset;
paths[drawobj_ix as usize] = path;
for i in 0..tile_count {
tiles[(offset + i) as usize] = Tile::default();
}
}
}
pub fn tile_alloc(_n_wg: u32, resources: &[CpuBinding]) {
let r0 = resources[0].as_buf();
let r1 = resources[1].as_buf();
let r2 = resources[2].as_buf();
let mut r3 = resources[3].as_buf();
let mut r4 = resources[4].as_buf();
let mut r5 = resources[5].as_buf();
let config = bytemuck::from_bytes(&r0);
let scene = bytemuck::cast_slice(&r1);
let draw_bboxes = bytemuck::cast_slice(&r2);
let bump = bytemuck::from_bytes_mut(r3.as_mut());
let paths = bytemuck::cast_slice_mut(r4.as_mut());
let tiles = bytemuck::cast_slice_mut(r5.as_mut());
tile_alloc_main(config, scene, draw_bboxes, bump, paths, tiles);
}