mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 20:51:29 +11:00
Merge pull request #77 from ishitatsuyuki/blend-scratch
Remove manual blend stack spilling and rely on scratch memory instead
This commit is contained in:
commit
bc7b2106b0
|
@ -148,12 +148,6 @@ void main() {
|
||||||
uint part_start_ix = 0;
|
uint part_start_ix = 0;
|
||||||
uint ready_ix = 0;
|
uint ready_ix = 0;
|
||||||
|
|
||||||
// Leave room for the fine rasterizer scratch allocation.
|
|
||||||
Alloc scratch_alloc = slice_mem(cmd_alloc, 0, Alloc_size);
|
|
||||||
cmd_ref.offset += Alloc_size;
|
|
||||||
|
|
||||||
uint num_begin_slots = 0;
|
|
||||||
uint begin_slot = 0;
|
|
||||||
bool mem_ok = mem_error == NO_ERROR;
|
bool mem_ok = mem_error == NO_ERROR;
|
||||||
while (true) {
|
while (true) {
|
||||||
for (uint i = 0; i < N_SLICE; i++) {
|
for (uint i = 0; i < N_SLICE; i++) {
|
||||||
|
@ -373,8 +367,6 @@ void main() {
|
||||||
if (clip_depth < 32) {
|
if (clip_depth < 32) {
|
||||||
clip_one_mask &= ~(1 << clip_depth);
|
clip_one_mask &= ~(1 << clip_depth);
|
||||||
}
|
}
|
||||||
begin_slot++;
|
|
||||||
num_begin_slots = max(num_begin_slots, begin_slot);
|
|
||||||
}
|
}
|
||||||
clip_depth++;
|
clip_depth++;
|
||||||
break;
|
break;
|
||||||
|
@ -386,7 +378,6 @@ void main() {
|
||||||
}
|
}
|
||||||
Cmd_Solid_write(cmd_alloc, cmd_ref);
|
Cmd_Solid_write(cmd_alloc, cmd_ref);
|
||||||
cmd_ref.offset += 4;
|
cmd_ref.offset += 4;
|
||||||
begin_slot--;
|
|
||||||
Cmd_EndClip_write(cmd_alloc, cmd_ref);
|
Cmd_EndClip_write(cmd_alloc, cmd_ref);
|
||||||
cmd_ref.offset += 4;
|
cmd_ref.offset += 4;
|
||||||
}
|
}
|
||||||
|
@ -414,13 +405,5 @@ void main() {
|
||||||
}
|
}
|
||||||
if (bin_tile_x + tile_x < conf.width_in_tiles && bin_tile_y + tile_y < conf.height_in_tiles) {
|
if (bin_tile_x + tile_x < conf.width_in_tiles && bin_tile_y + tile_y < conf.height_in_tiles) {
|
||||||
Cmd_End_write(cmd_alloc, cmd_ref);
|
Cmd_End_write(cmd_alloc, cmd_ref);
|
||||||
if (num_begin_slots > 0) {
|
|
||||||
// Write scratch allocation: one state per BeginClip per rasterizer chunk.
|
|
||||||
uint scratch_size = num_begin_slots * TILE_WIDTH_PX * TILE_HEIGHT_PX * CLIP_STATE_SIZE * 4;
|
|
||||||
MallocResult scratch = malloc(scratch_size);
|
|
||||||
// Ignore scratch.failed; we don't use the allocation and kernel4
|
|
||||||
// checks for memory overflow before using it.
|
|
||||||
alloc_write(scratch_alloc, scratch_alloc.offset, scratch.alloc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -37,6 +37,7 @@ layout(rgba8, set = 0, binding = 3) uniform restrict readonly image2D images[1];
|
||||||
#include "ptcl.h"
|
#include "ptcl.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
|
|
||||||
|
#define MAX_BLEND_STACK 128
|
||||||
mediump vec3 tosRGB(mediump vec3 rgb) {
|
mediump vec3 tosRGB(mediump vec3 rgb) {
|
||||||
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308));
|
bvec3 cutoff = greaterThanEqual(rgb, vec3(0.0031308));
|
||||||
mediump vec3 below = vec3(12.92)*rgb;
|
mediump vec3 below = vec3(12.92)*rgb;
|
||||||
|
@ -90,13 +91,11 @@ void main() {
|
||||||
Alloc cmd_alloc = slice_mem(conf.ptcl_alloc, tile_ix * PTCL_INITIAL_ALLOC, PTCL_INITIAL_ALLOC);
|
Alloc cmd_alloc = slice_mem(conf.ptcl_alloc, tile_ix * PTCL_INITIAL_ALLOC, PTCL_INITIAL_ALLOC);
|
||||||
CmdRef cmd_ref = CmdRef(cmd_alloc.offset);
|
CmdRef cmd_ref = CmdRef(cmd_alloc.offset);
|
||||||
|
|
||||||
// Read scrach space allocation, written first in the command list.
|
|
||||||
Alloc scratch_alloc = alloc_read(cmd_alloc, cmd_ref.offset);
|
|
||||||
cmd_ref.offset += Alloc_size;
|
|
||||||
|
|
||||||
uvec2 xy_uint = uvec2(gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_WorkGroupID.x, gl_LocalInvocationID.y + TILE_HEIGHT_PX * gl_WorkGroupID.y);
|
uvec2 xy_uint = uvec2(gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_WorkGroupID.x, gl_LocalInvocationID.y + TILE_HEIGHT_PX * gl_WorkGroupID.y);
|
||||||
vec2 xy = vec2(xy_uint);
|
vec2 xy = vec2(xy_uint);
|
||||||
mediump vec4 rgba[CHUNK];
|
mediump vec4 rgba[CHUNK];
|
||||||
|
uint blend_stack[MAX_BLEND_STACK][CHUNK];
|
||||||
|
mediump float blend_alpha_stack[MAX_BLEND_STACK][CHUNK];
|
||||||
for (uint i = 0; i < CHUNK; i++) {
|
for (uint i = 0; i < CHUNK; i++) {
|
||||||
rgba[i] = vec4(0.0);
|
rgba[i] = vec4(0.0);
|
||||||
// TODO: remove this debug image support when the actual image method is plumbed.
|
// TODO: remove this debug image support when the actual image method is plumbed.
|
||||||
|
@ -208,14 +207,12 @@ void main() {
|
||||||
cmd_ref.offset += 4 + CmdImage_size;
|
cmd_ref.offset += 4 + CmdImage_size;
|
||||||
break;
|
break;
|
||||||
case Cmd_BeginClip:
|
case Cmd_BeginClip:
|
||||||
uint base_ix = (scratch_alloc.offset >> 2) + CLIP_STATE_SIZE * (clip_depth * TILE_WIDTH_PX * TILE_HEIGHT_PX +
|
|
||||||
gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_LocalInvocationID.y);
|
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
uvec2 offset = chunk_offset(k);
|
// We reject any inputs that might overflow in render_ctx.rs.
|
||||||
uint srgb = packsRGB(vec4(rgba[k]));
|
// The following is a sanity check so we don't corrupt memory should there be malformed inputs.
|
||||||
mediump float alpha = clamp(abs(area[k]), 0.0, 1.0);
|
uint d = min(clip_depth, MAX_BLEND_STACK - 1);
|
||||||
write_mem(scratch_alloc, base_ix + 0 + CLIP_STATE_SIZE * (offset.x + offset.y * TILE_WIDTH_PX), srgb);
|
blend_stack[d][k] = packsRGB(vec4(rgba[k]));
|
||||||
write_mem(scratch_alloc, base_ix + 1 + CLIP_STATE_SIZE * (offset.x + offset.y * TILE_WIDTH_PX), floatBitsToUint(alpha));
|
blend_alpha_stack[d][k] = clamp(abs(area[k]), 0.0, 1.0);
|
||||||
rgba[k] = vec4(0.0);
|
rgba[k] = vec4(0.0);
|
||||||
}
|
}
|
||||||
clip_depth++;
|
clip_depth++;
|
||||||
|
@ -223,14 +220,10 @@ void main() {
|
||||||
break;
|
break;
|
||||||
case Cmd_EndClip:
|
case Cmd_EndClip:
|
||||||
clip_depth--;
|
clip_depth--;
|
||||||
base_ix = (scratch_alloc.offset >> 2) + CLIP_STATE_SIZE * (clip_depth * TILE_WIDTH_PX * TILE_HEIGHT_PX +
|
|
||||||
gl_LocalInvocationID.x + TILE_WIDTH_PX * gl_LocalInvocationID.y);
|
|
||||||
for (uint k = 0; k < CHUNK; k++) {
|
for (uint k = 0; k < CHUNK; k++) {
|
||||||
uvec2 offset = chunk_offset(k);
|
uint d = min(clip_depth, MAX_BLEND_STACK - 1);
|
||||||
uint srgb = read_mem(scratch_alloc, base_ix + 0 + CLIP_STATE_SIZE * (offset.x + offset.y * TILE_WIDTH_PX));
|
mediump vec4 bg = unpacksRGB(blend_stack[d][k]);
|
||||||
uint alpha = read_mem(scratch_alloc, base_ix + 1 + CLIP_STATE_SIZE * (offset.x + offset.y * TILE_WIDTH_PX));
|
mediump vec4 fg = rgba[k] * area[k] * blend_alpha_stack[d][k];
|
||||||
mediump vec4 bg = unpacksRGB(srgb);
|
|
||||||
mediump vec4 fg = rgba[k] * area[k] * uintBitsToFloat(alpha);
|
|
||||||
rgba[k] = bg * (1.0 - fg.a) + fg;
|
rgba[k] = bg * (1.0 - fg.a) + fg;
|
||||||
}
|
}
|
||||||
cmd_ref.offset += 4;
|
cmd_ref.offset += 4;
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -30,6 +30,8 @@ const WIDTH_IN_TILES: usize = 128;
|
||||||
const HEIGHT_IN_TILES: usize = 96;
|
const HEIGHT_IN_TILES: usize = 96;
|
||||||
const PTCL_INITIAL_ALLOC: usize = 1024;
|
const PTCL_INITIAL_ALLOC: usize = 1024;
|
||||||
|
|
||||||
|
const MAX_BLEND_STACK: usize = 128;
|
||||||
|
|
||||||
const N_CIRCLES: usize = 0;
|
const N_CIRCLES: usize = 0;
|
||||||
|
|
||||||
pub fn render_svg(rc: &mut impl RenderContext, filename: &str, scale: f64) {
|
pub fn render_svg(rc: &mut impl RenderContext, filename: &str, scale: f64) {
|
||||||
|
|
|
@ -8,6 +8,7 @@ use piet::{
|
||||||
Color, Error, FixedGradient, FontFamily, HitTestPoint, ImageFormat, InterpolationMode,
|
Color, Error, FixedGradient, FontFamily, HitTestPoint, ImageFormat, InterpolationMode,
|
||||||
IntoBrush, LineMetric, RenderContext, StrokeStyle, Text, TextLayout, TextLayoutBuilder,
|
IntoBrush, LineMetric, RenderContext, StrokeStyle, Text, TextLayout, TextLayoutBuilder,
|
||||||
};
|
};
|
||||||
|
use crate::MAX_BLEND_STACK;
|
||||||
|
|
||||||
use piet_gpu_types::encoder::{Encode, Encoder};
|
use piet_gpu_types::encoder::{Encode, Encoder};
|
||||||
use piet_gpu_types::scene::{
|
use piet_gpu_types::scene::{
|
||||||
|
@ -211,6 +212,9 @@ impl RenderContext for PietGpuRenderContext {
|
||||||
self.elements.push(Element::BeginClip(Clip {
|
self.elements.push(Element::BeginClip(Clip {
|
||||||
bbox: Default::default(),
|
bbox: Default::default(),
|
||||||
}));
|
}));
|
||||||
|
if self.clip_stack.len() >= MAX_BLEND_STACK {
|
||||||
|
panic!("Maximum clip/blend stack size {} exceeded", MAX_BLEND_STACK);
|
||||||
|
}
|
||||||
self.clip_stack.push(ClipElement {
|
self.clip_stack.push(ClipElement {
|
||||||
bbox: None,
|
bbox: None,
|
||||||
begin_ix,
|
begin_ix,
|
||||||
|
|
Loading…
Reference in a new issue