mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 12:41:30 +11:00
add support for element flags to shaders
Commit 9afa9b86b6
added Rust support for
encoding flags into elements. This change adds support to shaders by
introducing variant tag structs:
struct VariantTag {
uint tag;
uint flags;
}
and returning them from Variant_tag functions.
It also adds a flags argument to write functions for enum variants that
include TagFlags.
No functionality changes.
Updates #70
Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
parent
903ab1fb59
commit
a5b6bda941
|
@ -29,6 +29,7 @@ pub fn gen_glsl(module: &LayoutModule) -> String {
|
|||
(size, LayoutTypeDef::Enum(en)) => {
|
||||
gen_enum_def(&mut r, name, en);
|
||||
gen_item_def(&mut r, name, size.size);
|
||||
gen_tag_def(&mut r, name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +93,13 @@ fn gen_item_def(r: &mut String, name: &str, size: usize) {
|
|||
writeln!(r, "}}\n").unwrap();
|
||||
}
|
||||
|
||||
fn gen_tag_def(r: &mut String, name: &str) {
|
||||
writeln!(r, "struct {}Tag {{", name).unwrap();
|
||||
writeln!(r, " uint tag;").unwrap();
|
||||
writeln!(r, " uint flags;").unwrap();
|
||||
writeln!(r, "}};\n").unwrap();
|
||||
}
|
||||
|
||||
fn gen_struct_read(
|
||||
r: &mut String,
|
||||
bufname: &str,
|
||||
|
@ -143,12 +151,13 @@ fn gen_enum_read(
|
|||
variants: &[(String, Vec<(usize, LayoutType)>)],
|
||||
) {
|
||||
if is_mem {
|
||||
writeln!(r, "uint {}_tag(Alloc a, {}Ref ref) {{", name, name).unwrap();
|
||||
writeln!(r, " return read_mem(a, ref.offset >> 2);").unwrap();
|
||||
writeln!(r, "{}Tag {}_tag(Alloc a, {}Ref ref) {{", name, name, name).unwrap();
|
||||
writeln!(r, " uint tag_and_flags = read_mem(a, ref.offset >> 2);").unwrap();
|
||||
} else {
|
||||
writeln!(r, "uint {}_tag({}Ref ref) {{", name, name).unwrap();
|
||||
writeln!(r, " return {}[ref.offset >> 2];", bufname).unwrap();
|
||||
writeln!(r, "{}Tag {}_tag({}Ref ref) {{", name, name, name).unwrap();
|
||||
writeln!(r, " uint tag_and_flags = {}[ref.offset >> 2];", bufname).unwrap();
|
||||
}
|
||||
writeln!(r, " return {}Tag(tag_and_flags & 0xffff, tag_and_flags >> 16);", name).unwrap();
|
||||
writeln!(r, "}}\n").unwrap();
|
||||
for (var_name, payload) in variants {
|
||||
let payload_ix = if payload.len() == 1 {
|
||||
|
@ -555,6 +564,49 @@ fn gen_enum_write(
|
|||
}
|
||||
writeln!(r, "}}\n").unwrap();
|
||||
}
|
||||
} else if payload.len() == 2 && matches!(payload[0].1.ty, GpuType::Scalar(GpuScalar::TagFlags)) {
|
||||
if let GpuType::InlineStruct(structname) = &payload[1].1.ty {
|
||||
if is_mem {
|
||||
writeln!(
|
||||
r,
|
||||
"void {}_{}_write(Alloc a, {}Ref ref, uint flags, {} s) {{",
|
||||
name, var_name, name, structname
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
r,
|
||||
" write_mem(a, ref.offset >> 2, (flags << 16) | {}_{});",
|
||||
name, var_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
r,
|
||||
" {}_write(a, {}Ref(ref.offset + {}), s);",
|
||||
structname, structname, payload[0].0
|
||||
)
|
||||
.unwrap();
|
||||
} else {
|
||||
writeln!(
|
||||
r,
|
||||
"void {}_{}_write({}Ref ref, uint flags, {} s) {{",
|
||||
name, var_name, name, structname
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
r,
|
||||
" {}[ref.offset >> 2] = (flags << 16) | {}_{};",
|
||||
bufname, name, var_name
|
||||
)
|
||||
.unwrap();
|
||||
writeln!(
|
||||
r,
|
||||
" {}_write({}Ref(ref.offset + {}), s);",
|
||||
structname, structname, payload[0].0
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
writeln!(r, "}}\n").unwrap();
|
||||
}
|
||||
}
|
||||
// TODO: support for variants that aren't one struct.
|
||||
}
|
||||
|
|
|
@ -79,6 +79,11 @@ AnnotatedRef Annotated_index(AnnotatedRef ref, uint index) {
|
|||
return AnnotatedRef(ref.offset + index * Annotated_size);
|
||||
}
|
||||
|
||||
struct AnnotatedTag {
|
||||
uint tag;
|
||||
uint flags;
|
||||
};
|
||||
|
||||
AnnoFill AnnoFill_read(Alloc a, AnnoFillRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
|
@ -170,8 +175,9 @@ void AnnoClip_write(Alloc a, AnnoClipRef ref, AnnoClip s) {
|
|||
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||
}
|
||||
|
||||
uint Annotated_tag(Alloc a, AnnotatedRef ref) {
|
||||
return read_mem(a, ref.offset >> 2);
|
||||
AnnotatedTag Annotated_tag(Alloc a, AnnotatedRef ref) {
|
||||
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||
return AnnotatedTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||
}
|
||||
|
||||
AnnoStroke Annotated_Stroke_read(Alloc a, AnnotatedRef ref) {
|
||||
|
|
|
@ -46,7 +46,7 @@ void main() {
|
|||
// Work assignment: 1 thread : 1 path element
|
||||
uint row_count = 0;
|
||||
if (element_ix < conf.n_elements) {
|
||||
uint tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
uint tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
switch (tag) {
|
||||
case Annotated_Fill:
|
||||
case Annotated_FillImage:
|
||||
|
|
Binary file not shown.
|
@ -56,7 +56,7 @@ void main() {
|
|||
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||
uint tag = Annotated_Nop;
|
||||
if (element_ix < my_n_elements) {
|
||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
}
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
switch (tag) {
|
||||
|
|
Binary file not shown.
|
@ -196,7 +196,7 @@ void main() {
|
|||
if (th_ix + rd_ix < wr_ix) {
|
||||
element_ix = sh_elements[th_ix];
|
||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
}
|
||||
|
||||
// Bounding box of element in pixel coordinates.
|
||||
|
@ -256,7 +256,7 @@ void main() {
|
|||
}
|
||||
}
|
||||
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + sh_elements[el_ix] * Annotated_size);
|
||||
uint tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
uint tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
uint seq_ix = ix - (el_ix > 0 ? sh_tile_count[el_ix - 1] : 0);
|
||||
uint width = sh_tile_width[el_ix];
|
||||
uint x = sh_tile_x0[el_ix] + seq_ix % width;
|
||||
|
@ -305,7 +305,7 @@ void main() {
|
|||
// If that turns out to be expensive, maybe we can pack it into
|
||||
// shared memory (or perhaps just the tag).
|
||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
|
||||
if (clip_zero_depth == 0) {
|
||||
switch (tag) {
|
||||
|
|
Binary file not shown.
|
@ -99,7 +99,7 @@ State combine_state(State a, State b) {
|
|||
State map_element(ElementRef ref) {
|
||||
// TODO: it would *probably* be more efficient to make the memory read patterns less
|
||||
// divergent, though it would be more wasted memory.
|
||||
uint tag = Element_tag(ref);
|
||||
uint tag = Element_tag(ref).tag;
|
||||
State c;
|
||||
c.bbox = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
c.mat = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
@ -291,7 +291,7 @@ void main() {
|
|||
// gains to be had from stashing in shared memory or possibly
|
||||
// registers (though register pressure is an issue).
|
||||
ElementRef this_ref = Element_index(ref, i);
|
||||
uint tag = Element_tag(this_ref);
|
||||
uint tag = Element_tag(this_ref).tag;
|
||||
switch (tag) {
|
||||
case Element_FillLine:
|
||||
case Element_StrokeLine:
|
||||
|
|
Binary file not shown.
|
@ -161,7 +161,7 @@ void main() {
|
|||
}
|
||||
|
||||
while (true) {
|
||||
uint tag = Cmd_tag(cmd_alloc, cmd_ref);
|
||||
uint tag = Cmd_tag(cmd_alloc, cmd_ref).tag;
|
||||
if (tag == Cmd_End) {
|
||||
break;
|
||||
}
|
||||
|
|
Binary file not shown.
|
@ -96,7 +96,7 @@ void main() {
|
|||
|
||||
uint tag = PathSeg_Nop;
|
||||
if (element_ix < conf.n_pathseg) {
|
||||
tag = PathSeg_tag(conf.pathseg_alloc, ref);
|
||||
tag = PathSeg_tag(conf.pathseg_alloc, ref).tag;
|
||||
}
|
||||
switch (tag) {
|
||||
case PathSeg_FillCubic:
|
||||
|
|
Binary file not shown.
|
@ -54,6 +54,11 @@ PathSegRef PathSeg_index(PathSegRef ref, uint index) {
|
|||
return PathSegRef(ref.offset + index * PathSeg_size);
|
||||
}
|
||||
|
||||
struct PathSegTag {
|
||||
uint tag;
|
||||
uint flags;
|
||||
};
|
||||
|
||||
PathFillCubic PathFillCubic_read(Alloc a, PathFillCubicRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
|
@ -131,8 +136,9 @@ void PathStrokeCubic_write(Alloc a, PathStrokeCubicRef ref, PathStrokeCubic s) {
|
|||
write_mem(a, ix + 11, floatBitsToUint(s.stroke.y));
|
||||
}
|
||||
|
||||
uint PathSeg_tag(Alloc a, PathSegRef ref) {
|
||||
return read_mem(a, ref.offset >> 2);
|
||||
PathSegTag PathSeg_tag(Alloc a, PathSegRef ref) {
|
||||
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||
return PathSegTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||
}
|
||||
|
||||
PathFillCubic PathSeg_FillCubic_read(Alloc a, PathSegRef ref) {
|
||||
|
|
|
@ -157,6 +157,11 @@ CmdRef Cmd_index(CmdRef ref, uint index) {
|
|||
return CmdRef(ref.offset + index * Cmd_size);
|
||||
}
|
||||
|
||||
struct CmdTag {
|
||||
uint tag;
|
||||
uint flags;
|
||||
};
|
||||
|
||||
CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = read_mem(a, ix + 0);
|
||||
|
@ -301,8 +306,9 @@ void CmdJump_write(Alloc a, CmdJumpRef ref, CmdJump s) {
|
|||
write_mem(a, ix + 0, s.new_ref);
|
||||
}
|
||||
|
||||
uint Cmd_tag(Alloc a, CmdRef ref) {
|
||||
return read_mem(a, ref.offset >> 2);
|
||||
CmdTag Cmd_tag(Alloc a, CmdRef ref) {
|
||||
uint tag_and_flags = read_mem(a, ref.offset >> 2);
|
||||
return CmdTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||
}
|
||||
|
||||
CmdFill Cmd_Fill_read(Alloc a, CmdRef ref) {
|
||||
|
|
|
@ -160,6 +160,11 @@ ElementRef Element_index(ElementRef ref, uint index) {
|
|||
return ElementRef(ref.offset + index * Element_size);
|
||||
}
|
||||
|
||||
struct ElementTag {
|
||||
uint tag;
|
||||
uint flags;
|
||||
};
|
||||
|
||||
LineSeg LineSeg_read(LineSegRef ref) {
|
||||
uint ix = ref.offset >> 2;
|
||||
uint raw0 = scene[ix + 0];
|
||||
|
@ -264,8 +269,9 @@ Clip Clip_read(ClipRef ref) {
|
|||
return s;
|
||||
}
|
||||
|
||||
uint Element_tag(ElementRef ref) {
|
||||
return scene[ref.offset >> 2];
|
||||
ElementTag Element_tag(ElementRef ref) {
|
||||
uint tag_and_flags = scene[ref.offset >> 2];
|
||||
return ElementTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||
}
|
||||
|
||||
LineSeg Element_StrokeLine_read(ElementRef ref) {
|
||||
|
|
|
@ -39,7 +39,7 @@ void main() {
|
|||
|
||||
uint tag = Annotated_Nop;
|
||||
if (element_ix < conf.n_elements) {
|
||||
tag = Annotated_tag(conf.anno_alloc, ref);
|
||||
tag = Annotated_tag(conf.anno_alloc, ref).tag;
|
||||
}
|
||||
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||
switch (tag) {
|
||||
|
|
Binary file not shown.
Loading…
Reference in a new issue