# HG changeset patch # User Simon Heath # Date 1565375894 14400 # Fri Aug 09 14:38:14 2019 -0400 # Node ID 5b451f601b899dcd86bb631548aaae94d5fb459c # Parent 382d3478fd0b676f465d9359a0911c96942923bc Define vector4f type. You can't actually do anything with it at the moment except construct it, so it's pretty easy! But hopefully that will be enough to get a shader actually functioning. diff --git a/examples/rendy.rs b/examples/rendy.rs --- a/examples/rendy.rs +++ b/examples/rendy.rs @@ -39,7 +39,6 @@ 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 @@ use rendy::mesh::AsVertex; - type Backend = rendy::vulkan::Backend; lazy_static::lazy_static! { diff --git a/src/ast.rs b/src/ast.rs --- a/src/ast.rs +++ b/src/ast.rs @@ -58,6 +58,7 @@ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize, PartialOrd)] pub enum Lit { F32(f32), + Vec4F(f32, f32, f32, f32), Bool(bool), Unit, } @@ -66,6 +67,7 @@ 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 @@ }; 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), } diff --git a/src/compile/mod.rs b/src/compile/mod.rs --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -74,7 +74,8 @@ // unit testing easier. use verify::TypeDef; s.add_type(&TypeDef::F32); - // vec4 + s.add_type(&TypeDef::Vec4F); + // Struct4 s.add_type(&TypeDef::Struct(vec![ ("x".into(), TypeDef::F32), ("y".into(), TypeDef::F32), @@ -137,26 +138,72 @@ // 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 @@ .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 @@ .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 @@ 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) }; diff --git a/src/verify.rs b/src/verify.rs --- a/src/verify.rs +++ b/src/verify.rs @@ -67,6 +67,7 @@ #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub enum TypeDef { F32, + Vec4F, Bool, Unit, Struct(Vec<(String, TypeDef)>), @@ -102,10 +103,11 @@ { // 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 @@ 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 @@ 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))),