mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 20:51:29 +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)) => {
|
(size, LayoutTypeDef::Enum(en)) => {
|
||||||
gen_enum_def(&mut r, name, en);
|
gen_enum_def(&mut r, name, en);
|
||||||
gen_item_def(&mut r, name, size.size);
|
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();
|
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(
|
fn gen_struct_read(
|
||||||
r: &mut String,
|
r: &mut String,
|
||||||
bufname: &str,
|
bufname: &str,
|
||||||
|
@ -143,12 +151,13 @@ fn gen_enum_read(
|
||||||
variants: &[(String, Vec<(usize, LayoutType)>)],
|
variants: &[(String, Vec<(usize, LayoutType)>)],
|
||||||
) {
|
) {
|
||||||
if is_mem {
|
if is_mem {
|
||||||
writeln!(r, "uint {}_tag(Alloc a, {}Ref ref) {{", name, name).unwrap();
|
writeln!(r, "{}Tag {}_tag(Alloc a, {}Ref ref) {{", name, name, name).unwrap();
|
||||||
writeln!(r, " return read_mem(a, ref.offset >> 2);").unwrap();
|
writeln!(r, " uint tag_and_flags = read_mem(a, ref.offset >> 2);").unwrap();
|
||||||
} else {
|
} else {
|
||||||
writeln!(r, "uint {}_tag({}Ref ref) {{", name, name).unwrap();
|
writeln!(r, "{}Tag {}_tag({}Ref ref) {{", name, name, name).unwrap();
|
||||||
writeln!(r, " return {}[ref.offset >> 2];", bufname).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();
|
writeln!(r, "}}\n").unwrap();
|
||||||
for (var_name, payload) in variants {
|
for (var_name, payload) in variants {
|
||||||
let payload_ix = if payload.len() == 1 {
|
let payload_ix = if payload.len() == 1 {
|
||||||
|
@ -555,6 +564,49 @@ fn gen_enum_write(
|
||||||
}
|
}
|
||||||
writeln!(r, "}}\n").unwrap();
|
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.
|
// 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);
|
return AnnotatedRef(ref.offset + index * Annotated_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct AnnotatedTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
AnnoFill AnnoFill_read(Alloc a, AnnoFillRef ref) {
|
AnnoFill AnnoFill_read(Alloc a, AnnoFillRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
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));
|
write_mem(a, ix + 3, floatBitsToUint(s.bbox.w));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Annotated_tag(Alloc a, AnnotatedRef ref) {
|
AnnotatedTag Annotated_tag(Alloc a, AnnotatedRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
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) {
|
AnnoStroke Annotated_Stroke_read(Alloc a, AnnotatedRef ref) {
|
||||||
|
|
|
@ -46,7 +46,7 @@ void main() {
|
||||||
// Work assignment: 1 thread : 1 path element
|
// Work assignment: 1 thread : 1 path element
|
||||||
uint row_count = 0;
|
uint row_count = 0;
|
||||||
if (element_ix < conf.n_elements) {
|
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) {
|
switch (tag) {
|
||||||
case Annotated_Fill:
|
case Annotated_Fill:
|
||||||
case Annotated_FillImage:
|
case Annotated_FillImage:
|
||||||
|
|
Binary file not shown.
|
@ -56,7 +56,7 @@ void main() {
|
||||||
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
AnnotatedRef ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
||||||
uint tag = Annotated_Nop;
|
uint tag = Annotated_Nop;
|
||||||
if (element_ix < my_n_elements) {
|
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;
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
|
|
Binary file not shown.
|
@ -196,7 +196,7 @@ void main() {
|
||||||
if (th_ix + rd_ix < wr_ix) {
|
if (th_ix + rd_ix < wr_ix) {
|
||||||
element_ix = sh_elements[th_ix];
|
element_ix = sh_elements[th_ix];
|
||||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
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.
|
// 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);
|
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 seq_ix = ix - (el_ix > 0 ? sh_tile_count[el_ix - 1] : 0);
|
||||||
uint width = sh_tile_width[el_ix];
|
uint width = sh_tile_width[el_ix];
|
||||||
uint x = sh_tile_x0[el_ix] + seq_ix % width;
|
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
|
// If that turns out to be expensive, maybe we can pack it into
|
||||||
// shared memory (or perhaps just the tag).
|
// shared memory (or perhaps just the tag).
|
||||||
ref = AnnotatedRef(conf.anno_alloc.offset + element_ix * Annotated_size);
|
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) {
|
if (clip_zero_depth == 0) {
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
|
|
Binary file not shown.
|
@ -99,7 +99,7 @@ State combine_state(State a, State b) {
|
||||||
State map_element(ElementRef ref) {
|
State map_element(ElementRef ref) {
|
||||||
// TODO: it would *probably* be more efficient to make the memory read patterns less
|
// TODO: it would *probably* be more efficient to make the memory read patterns less
|
||||||
// divergent, though it would be more wasted memory.
|
// divergent, though it would be more wasted memory.
|
||||||
uint tag = Element_tag(ref);
|
uint tag = Element_tag(ref).tag;
|
||||||
State c;
|
State c;
|
||||||
c.bbox = vec4(0.0, 0.0, 0.0, 0.0);
|
c.bbox = vec4(0.0, 0.0, 0.0, 0.0);
|
||||||
c.mat = vec4(1.0, 0.0, 0.0, 1.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
|
// gains to be had from stashing in shared memory or possibly
|
||||||
// registers (though register pressure is an issue).
|
// registers (though register pressure is an issue).
|
||||||
ElementRef this_ref = Element_index(ref, i);
|
ElementRef this_ref = Element_index(ref, i);
|
||||||
uint tag = Element_tag(this_ref);
|
uint tag = Element_tag(this_ref).tag;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case Element_FillLine:
|
case Element_FillLine:
|
||||||
case Element_StrokeLine:
|
case Element_StrokeLine:
|
||||||
|
|
Binary file not shown.
|
@ -161,7 +161,7 @@ void main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
uint tag = Cmd_tag(cmd_alloc, cmd_ref);
|
uint tag = Cmd_tag(cmd_alloc, cmd_ref).tag;
|
||||||
if (tag == Cmd_End) {
|
if (tag == Cmd_End) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -96,7 +96,7 @@ void main() {
|
||||||
|
|
||||||
uint tag = PathSeg_Nop;
|
uint tag = PathSeg_Nop;
|
||||||
if (element_ix < conf.n_pathseg) {
|
if (element_ix < conf.n_pathseg) {
|
||||||
tag = PathSeg_tag(conf.pathseg_alloc, ref);
|
tag = PathSeg_tag(conf.pathseg_alloc, ref).tag;
|
||||||
}
|
}
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case PathSeg_FillCubic:
|
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);
|
return PathSegRef(ref.offset + index * PathSeg_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct PathSegTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
PathFillCubic PathFillCubic_read(Alloc a, PathFillCubicRef ref) {
|
PathFillCubic PathFillCubic_read(Alloc a, PathFillCubicRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
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));
|
write_mem(a, ix + 11, floatBitsToUint(s.stroke.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint PathSeg_tag(Alloc a, PathSegRef ref) {
|
PathSegTag PathSeg_tag(Alloc a, PathSegRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
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) {
|
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);
|
return CmdRef(ref.offset + index * Cmd_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CmdTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) {
|
CmdStroke CmdStroke_read(Alloc a, CmdStrokeRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = read_mem(a, ix + 0);
|
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);
|
write_mem(a, ix + 0, s.new_ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Cmd_tag(Alloc a, CmdRef ref) {
|
CmdTag Cmd_tag(Alloc a, CmdRef ref) {
|
||||||
return read_mem(a, ref.offset >> 2);
|
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) {
|
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);
|
return ElementRef(ref.offset + index * Element_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ElementTag {
|
||||||
|
uint tag;
|
||||||
|
uint flags;
|
||||||
|
};
|
||||||
|
|
||||||
LineSeg LineSeg_read(LineSegRef ref) {
|
LineSeg LineSeg_read(LineSegRef ref) {
|
||||||
uint ix = ref.offset >> 2;
|
uint ix = ref.offset >> 2;
|
||||||
uint raw0 = scene[ix + 0];
|
uint raw0 = scene[ix + 0];
|
||||||
|
@ -264,8 +269,9 @@ Clip Clip_read(ClipRef ref) {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint Element_tag(ElementRef ref) {
|
ElementTag Element_tag(ElementRef ref) {
|
||||||
return scene[ref.offset >> 2];
|
uint tag_and_flags = scene[ref.offset >> 2];
|
||||||
|
return ElementTag(tag_and_flags & 0xffff, tag_and_flags >> 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
LineSeg Element_StrokeLine_read(ElementRef ref) {
|
LineSeg Element_StrokeLine_read(ElementRef ref) {
|
||||||
|
|
|
@ -39,7 +39,7 @@ void main() {
|
||||||
|
|
||||||
uint tag = Annotated_Nop;
|
uint tag = Annotated_Nop;
|
||||||
if (element_ix < conf.n_elements) {
|
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;
|
int x0 = 0, y0 = 0, x1 = 0, y1 = 0;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
|
|
Binary file not shown.
Loading…
Reference in a new issue