M examples/rendy.rs +0 -2
@@ 39,7 39,6 @@ fn compile_shader() -> Vec<u8> {
returns: Type("F32".into()),
//body: vec![Expr::Var("input".into())],
body: vec![Expr::Literal(Lit::F32(0.1))],
-
});
let program = vec![vert, frag];
let ctx = ch::verify::verify(program).unwrap();
@@ 50,7 49,6 @@ fn compile_shader() -> Vec<u8> {
use rendy::mesh::AsVertex;
-
type Backend = rendy::vulkan::Backend;
lazy_static::lazy_static! {
M src/ast.rs +12 -0
@@ 58,6 58,7 @@ pub enum Decl {
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, PartialOrd)]
pub enum Lit {
F32(f32),
+ Vec4F(f32, f32, f32, f32),
Bool(bool),
Unit,
}
@@ 66,6 67,7 @@ impl Lit {
pub fn type_of(&self) -> Type {
match self {
Lit::F32(_) => Type("F32".into()),
+ Lit::Vec4F(_, _, _, _) => Type("Vec4F".into()),
Lit::Bool(_) => Type("Bool".into()),
Lit::Unit => Type("()".into()),
}
@@ 92,6 94,16 @@ impl std::hash::Hash for Lit {
};
f_bits.hash(state)
}
+ Lit::Vec4F(x, y, z, w) => {
+ for f in &[x, y, z, w][..] {
+ let f_bits = if f.is_nan() {
+ std::f32::NAN.to_bits()
+ } else {
+ f.to_bits()
+ };
+ f_bits.hash(state)
+ }
+ }
Lit::Bool(b) => b.hash(state),
Lit::Unit => ().hash(state),
}
M src/compile/mod.rs +85 -19
@@ 74,7 74,8 @@ impl CContext {
// unit testing easier.
use verify::TypeDef;
s.add_type(&TypeDef::F32);
- // vec4<f32>
+ s.add_type(&TypeDef::Vec4F);
+ // Struct4<f32>
s.add_type(&TypeDef::Struct(vec![
("x".into(), TypeDef::F32),
("y".into(), TypeDef::F32),
@@ 137,26 138,72 @@ impl CContext {
// causes borrowing issues. :|
let type_float = self.get_type(&verify::TypeDef::F32);
let type_bool = self.get_type(&verify::TypeDef::Bool);
+ let type_vec4f = self.get_type(&verify::TypeDef::Vec4F);
//let type_unit = self.get_type(&verify::TypeDef::Unit);
let consts = &mut self.consts;
- let b = &mut self.b;
- *consts.entry(vl.clone()).or_insert_with(|| match vl {
- ast::Lit::F32(f) => b.constant_f32(type_float, f),
- ast::Lit::Bool(bl) => {
- if bl {
- b.constant_true(type_bool)
- } else {
- b.constant_false(type_bool)
+ // Entry API doesn't work here 'cause we might have to recursively
+ // make several modifications to the type table.
+ if let Some(res) = consts.get(&vl) {
+ *res
+ } else {
+ match vl {
+ ast::Lit::F32(f) => self.b.constant_f32(type_float, f),
+ ast::Lit::Bool(bl) => {
+ if bl {
+ self.b.constant_true(type_bool)
+ } else {
+ self.b.constant_false(type_bool)
+ }
+ }
+ ast::Lit::Vec4F(x, y, z, w) => {
+ let components = [
+ self.define_const(ast::Lit::F32(x)),
+ self.define_const(ast::Lit::F32(y)),
+ self.define_const(ast::Lit::F32(z)),
+ self.define_const(ast::Lit::F32(w)),
+ ];
+ self.b.constant_composite(type_vec4f, &components)
+ }
+ // TODO: This is WRONG WRONG WRONG but
+ // I'm not entirely sure how to make it right
+ // yet. Unit is not actually a value, so.
+ ast::Lit::Unit => {
+ 0;
+ unimplemented!()
+ //b.constant_null(type_unit),
}
}
- // TODO: This is WRONG WRONG WRONG but
- // I'm not entirely sure how to make it right
- // yet. Unit is not actually a value, so.
- ast::Lit::Unit =>
- 0
- //b.constant_null(type_unit),
- })
+ }
+ /*
+ *consts.entry(vl.clone()).or_insert_with(|| match vl {
+ ast::Lit::F32(f) => b.constant_f32(type_float, f),
+ ast::Lit::Bool(bl) => {
+ if bl {
+ b.constant_true(type_bool)
+ } else {
+ b.constant_false(type_bool)
+ }
+ }
+ ast::Lit::Vec4F(x, y, z, w) => {
+ let components = [
+ self.define_const(ast::Lit::F32(x)),
+ self.define_const(ast::Lit::F32(y)),
+ self.define_const(ast::Lit::F32(z)),
+ self.define_const(ast::Lit::F32(w)),
+ ];
+ b.constant_composite(type_vec4f, &components)
+ }
+ // TODO: This is WRONG WRONG WRONG but
+ // I'm not entirely sure how to make it right
+ // yet. Unit is not actually a value, so.
+ ast::Lit::Unit => {
+ unimplemented!();
+ 0
+ //b.constant_null(type_unit),
+ }
+ })
+ */
}
/// Panics if the type does not exist.
@@ 192,6 239,17 @@ impl CContext {
.entry(typedef.clone())
.or_insert_with(|| b.type_float(32))
}
+ TypeDef::Vec4F => {
+ if let Some(val) = self.typetable.get(typedef) {
+ // Vec4F already exists
+ *val
+ } else {
+ let f_type_word = self.add_type(&verify::TypeDef::F32);
+ let vec_type_word = self.b.type_vector(f_type_word, 4);
+ self.typetable.insert(typedef.clone(), vec_type_word);
+ vec_type_word
+ }
+ }
TypeDef::Bool => {
let b = &mut self.b;
*self
@@ 625,7 683,11 @@ impl CContext {
.variable(t_ptr_word, None, spirv::StorageClass::Input, None);
// Gotta tell it what locations/etc the inputs are.
// FOR NOW we just enumerate the function args in order.
- self.b.decorate(value_word, spirv::Decoration::Location, [rspirv::mr::Operand::LiteralInt32(u32::try_from(i).unwrap())]);
+ self.b.decorate(
+ value_word,
+ spirv::Decoration::Location,
+ [rspirv::mr::Operand::LiteralInt32(u32::try_from(i).unwrap())],
+ );
(value_word, t_word, t_ptr_word)
})
.collect();
@@ 638,8 700,12 @@ impl CContext {
let value_word =
self.b
.variable(t_ptr_word, None, spirv::StorageClass::Output, None);
- // Output word is always just location=0
- self.b.decorate(value_word, spirv::Decoration::Location, [rspirv::mr::Operand::LiteralInt32(0)]);
+ // Output word is always just location=0
+ self.b.decorate(
+ value_word,
+ spirv::Decoration::Location,
+ [rspirv::mr::Operand::LiteralInt32(0)],
+ );
(value_word, t_word, t_ptr_word)
};
M src/verify.rs +7 -5
@@ 67,6 67,7 @@ use crate::Error;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum TypeDef {
F32,
+ Vec4F,
Bool,
Unit,
Struct(Vec<(String, TypeDef)>),
@@ 102,10 103,11 @@ impl Default for VContext {
{
// Default types.
types.insert("F32".into(), TypeDef::F32);
+ types.insert("Vec4F".into(), TypeDef::Vec4F);
types.insert("Bool".into(), TypeDef::Bool);
types.insert("()".into(), TypeDef::Unit);
types.insert(
- "Vec4F".into(),
+ "Struct4F".into(),
TypeDef::Struct(vec![
("x".into(), TypeDef::F32),
("y".into(), TypeDef::F32),
@@ 310,9 312,9 @@ mod tests {
let vert = Decl::Function(FunctionDecl {
name: String::from("vertex"),
params: vec![],
- returns: Type("Vec4F".into()),
+ returns: Type("Struct4F".into()),
body: vec![Expr::Structure(
- String::from("Vec4F"),
+ String::from("Struct4F"),
vec![
(String::from("x"), Expr::Literal(Lit::F32(1.0))),
(String::from("y"), Expr::Literal(Lit::F32(1.0))),
@@ 352,9 354,9 @@ mod tests {
let f = Decl::Function(FunctionDecl {
name: String::from("foo"),
params: vec![],
- returns: Type("Vec4F".into()),
+ returns: Type("Struct4F".into()),
body: vec![Expr::Structure(
- String::from("Vec4F"),
+ String::from("Struct4F"),
vec![
(String::from("x"), Expr::Literal(Lit::F32(1.0))),
(String::from("y"), Expr::Literal(Lit::F32(1.0))),