mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-10 20:51:29 +11:00
Add encoding of flags into tag
Add a `TagFlags` type. You can write enum variants as `Variant(TagFlags, Content)` and this will encode a u16 into the top 16 bits of the tag word.
This commit is contained in:
parent
b73eabf4eb
commit
9afa9b86b6
|
@ -73,18 +73,31 @@ fn gen_derive_def(name: &str, size: usize, def: &LayoutTypeDef) -> proc_macro2::
|
||||||
|
|
||||||
let mut args = Vec::new();
|
let mut args = Vec::new();
|
||||||
let mut field_encoders = proc_macro2::TokenStream::new();
|
let mut field_encoders = proc_macro2::TokenStream::new();
|
||||||
for (i, (offset, _ty)) in payload.iter().enumerate() {
|
let mut tag_field = None;
|
||||||
|
for (i, (offset, ty)) in payload.iter().enumerate() {
|
||||||
let field_id = format_ident!("f{}", i);
|
let field_id = format_ident!("f{}", i);
|
||||||
|
if matches!(ty.ty, GpuType::Scalar(GpuScalar::TagFlags)) {
|
||||||
|
tag_field = Some(field_id.clone());
|
||||||
|
} else {
|
||||||
let field_encoder = quote! {
|
let field_encoder = quote! {
|
||||||
#field_id.encode_to(&mut buf[#offset..]);
|
#field_id.encode_to(&mut buf[#offset..]);
|
||||||
};
|
};
|
||||||
field_encoders.extend(field_encoder);
|
field_encoders.extend(field_encoder);
|
||||||
|
}
|
||||||
args.push(field_id);
|
args.push(field_id);
|
||||||
}
|
}
|
||||||
let tag = variant_ix as u32;
|
let tag = variant_ix as u32;
|
||||||
|
let tag_encode = match tag_field {
|
||||||
|
None => quote! {
|
||||||
|
buf[0..4].copy_from_slice(&#tag.to_le_bytes());
|
||||||
|
},
|
||||||
|
Some(tag_field) => quote! {
|
||||||
|
buf[0..4].copy_from_slice(&(#tag | ((*#tag_field as u32) << 16)).to_le_bytes());
|
||||||
|
},
|
||||||
|
};
|
||||||
let case = quote! {
|
let case = quote! {
|
||||||
#name_id::#variant_id(#(#args),*) => {
|
#name_id::#variant_id(#(#args),*) => {
|
||||||
buf[0..4].copy_from_slice(&#tag.to_le_bytes());
|
#tag_encode
|
||||||
#field_encoders
|
#field_encoders
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -139,12 +152,15 @@ fn gen_derive_scalar_ty(ty: &GpuScalar) -> proc_macro2::TokenStream {
|
||||||
GpuScalar::U8 => quote!(u8),
|
GpuScalar::U8 => quote!(u8),
|
||||||
GpuScalar::U16 => quote!(u16),
|
GpuScalar::U16 => quote!(u16),
|
||||||
GpuScalar::U32 => quote!(u32),
|
GpuScalar::U32 => quote!(u32),
|
||||||
|
GpuScalar::TagFlags => quote!(u16),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn gen_encode_field(name: &str, offset: usize, ty: &GpuType) -> proc_macro2::TokenStream {
|
fn gen_encode_field(name: &str, offset: usize, ty: &GpuType) -> proc_macro2::TokenStream {
|
||||||
let name_id = format_ident!("{}", name);
|
let name_id = format_ident!("{}", name);
|
||||||
match ty {
|
match ty {
|
||||||
|
// encoding of flags into tag word is handled elsewhere
|
||||||
|
GpuType::Scalar(GpuScalar::TagFlags) => quote! {},
|
||||||
GpuType::Scalar(s) => {
|
GpuType::Scalar(s) => {
|
||||||
let end = offset + s.size();
|
let end = offset + s.size();
|
||||||
quote! {
|
quote! {
|
||||||
|
|
|
@ -8,7 +8,11 @@ use crate::parse::{GpuScalar, GpuType};
|
||||||
|
|
||||||
pub fn gen_glsl(module: &LayoutModule) -> String {
|
pub fn gen_glsl(module: &LayoutModule) -> String {
|
||||||
let mut r = String::new();
|
let mut r = String::new();
|
||||||
writeln!(&mut r, "// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense\n").unwrap();
|
writeln!(
|
||||||
|
&mut r,
|
||||||
|
"// SPDX-License-Identifier: Apache-2.0 OR MIT OR Unlicense\n"
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
writeln!(&mut r, "// Code auto-generated by piet-gpu-derive\n").unwrap();
|
writeln!(&mut r, "// Code auto-generated by piet-gpu-derive\n").unwrap();
|
||||||
// Note: GLSL needs definitions before uses. We could do a topological sort here,
|
// Note: GLSL needs definitions before uses. We could do a topological sort here,
|
||||||
// but easiest for now to just require that in spec.
|
// but easiest for now to just require that in spec.
|
||||||
|
@ -147,8 +151,19 @@ fn gen_enum_read(
|
||||||
}
|
}
|
||||||
writeln!(r, "}}\n").unwrap();
|
writeln!(r, "}}\n").unwrap();
|
||||||
for (var_name, payload) in variants {
|
for (var_name, payload) in variants {
|
||||||
if payload.len() == 1 {
|
let payload_ix = if payload.len() == 1 {
|
||||||
if let GpuType::InlineStruct(structname) = &payload[0].1.ty {
|
Some(0)
|
||||||
|
} else if payload.len() == 2 {
|
||||||
|
if matches!(payload[0].1.ty, GpuType::Scalar(GpuScalar::TagFlags)) {
|
||||||
|
Some(1)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
if let Some(payload_ix) = payload_ix {
|
||||||
|
if let GpuType::InlineStruct(structname) = &payload[payload_ix].1.ty {
|
||||||
if is_mem {
|
if is_mem {
|
||||||
writeln!(
|
writeln!(
|
||||||
r,
|
r,
|
||||||
|
@ -257,6 +272,7 @@ fn gen_extract_scalar(offset: usize, ty: &GpuScalar) -> String {
|
||||||
GpuScalar::F16 | GpuScalar::F32 => extract_fbits(offset, ty.size()),
|
GpuScalar::F16 | GpuScalar::F32 => extract_fbits(offset, ty.size()),
|
||||||
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 => extract_ubits(offset, ty.size()),
|
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 => extract_ubits(offset, ty.size()),
|
||||||
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => extract_ibits(offset, ty.size()),
|
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => extract_ibits(offset, ty.size()),
|
||||||
|
GpuScalar::TagFlags => format!("0 /* TODO */"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,6 +471,7 @@ fn gen_pack_bits_scalar(ty: &GpuScalar, offset: usize, inner: &str) -> String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GpuScalar::I32 => format!("uint({})", inner),
|
GpuScalar::I32 => format!("uint({})", inner),
|
||||||
|
GpuScalar::TagFlags => format!("0"),
|
||||||
};
|
};
|
||||||
if shift == 0 {
|
if shift == 0 {
|
||||||
bits
|
bits
|
||||||
|
@ -473,7 +490,12 @@ fn gen_enum_write(
|
||||||
for (var_name, payload) in variants {
|
for (var_name, payload) in variants {
|
||||||
if payload.is_empty() {
|
if payload.is_empty() {
|
||||||
if is_mem {
|
if is_mem {
|
||||||
writeln!(r, "void {}_{}_write(Alloc a, {}Ref ref) {{", name, var_name, name).unwrap();
|
writeln!(
|
||||||
|
r,
|
||||||
|
"void {}_{}_write(Alloc a, {}Ref ref) {{",
|
||||||
|
name, var_name, name
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
writeln!(
|
writeln!(
|
||||||
r,
|
r,
|
||||||
" write_mem(a, ref.offset >> 2, {}_{});",
|
" write_mem(a, ref.offset >> 2, {}_{});",
|
||||||
|
@ -566,7 +588,7 @@ fn glsl_scalar(s: &GpuScalar) -> &'static str {
|
||||||
match s {
|
match s {
|
||||||
GpuScalar::F16 | GpuScalar::F32 => "float",
|
GpuScalar::F16 | GpuScalar::F32 => "float",
|
||||||
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => "int",
|
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => "int",
|
||||||
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 => "uint",
|
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 | GpuScalar::TagFlags => "uint",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,7 +596,7 @@ fn glsl_vecname(s: &GpuScalar) -> &'static str {
|
||||||
match s {
|
match s {
|
||||||
GpuScalar::F16 | GpuScalar::F32 => "vec",
|
GpuScalar::F16 | GpuScalar::F32 => "vec",
|
||||||
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => "ivec",
|
GpuScalar::I8 | GpuScalar::I16 | GpuScalar::I32 => "ivec",
|
||||||
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 => "uvec",
|
GpuScalar::U8 | GpuScalar::U16 | GpuScalar::U32 | GpuScalar::TagFlags => "uvec",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -240,5 +240,5 @@ impl Size {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn align_padding(offset: usize, alignment: usize) -> usize {
|
fn align_padding(offset: usize, alignment: usize) -> usize {
|
||||||
offset.wrapping_neg() & (alignment - 1)
|
offset.wrapping_neg() & (alignment.max(1) - 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ pub enum GpuScalar {
|
||||||
U8,
|
U8,
|
||||||
U16,
|
U16,
|
||||||
U32,
|
U32,
|
||||||
|
TagFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An algebraic datatype.
|
/// An algebraic datatype.
|
||||||
|
@ -59,6 +60,7 @@ impl GpuScalar {
|
||||||
"u8" => Some(GpuScalar::U8),
|
"u8" => Some(GpuScalar::U8),
|
||||||
"u16" => Some(GpuScalar::U16),
|
"u16" => Some(GpuScalar::U16),
|
||||||
"u32" => Some(GpuScalar::U32),
|
"u32" => Some(GpuScalar::U32),
|
||||||
|
"TagFlags" => Some(GpuScalar::TagFlags),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -72,6 +74,7 @@ impl GpuScalar {
|
||||||
GpuScalar::F32 | GpuScalar::I32 | GpuScalar::U32 => 4,
|
GpuScalar::F32 | GpuScalar::I32 | GpuScalar::U32 => 4,
|
||||||
GpuScalar::I8 | GpuScalar::U8 => 1,
|
GpuScalar::I8 | GpuScalar::U8 => 1,
|
||||||
GpuScalar::F16 | GpuScalar::I16 | GpuScalar::U16 => 2,
|
GpuScalar::F16 | GpuScalar::I16 | GpuScalar::U16 => 2,
|
||||||
|
GpuScalar::TagFlags => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue