@@ 23,12 23,18 @@ fn compile_shader() -> Vec<u8> {
use ch::ast::*;
let vert = Decl::Function(FunctionDecl {
name: String::from("vertex"),
- params: vec![Param {
- name: "i".into(),
- typ: Type("F32".into()),
- }],
- returns: Type("F32".into()),
- body: vec![Expr::Var("i".into())],
+ params: vec![
+ Param {
+ name: "pos".into(),
+ typ: Type("Vec4F".into()),
+ },
+ Param {
+ name: "color".into(),
+ typ: Type("Vec4F".into()),
+ },
+ ],
+ returns: Type("Vec4F".into()),
+ body: vec![Expr::Var("color".into())],
});
let frag = Decl::Function(FunctionDecl {
name: String::from("fragment"),
@@ 144,6 144,7 @@ impl CContext {
let consts = &mut self.consts;
// Entry API doesn't work here 'cause we might have to recursively
// make several modifications to the type table.
+ // TODO: ...really, Vec4F is more of a constructor than a literal...
if let Some(res) = consts.get(&vl) {
*res
} else {
@@ 175,35 176,6 @@ impl CContext {
}
}
}
- /*
- *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.
@@ 324,22 296,6 @@ impl CContext {
let var_typedef = ctx.get_defined_type(&typ);
let var_typeword = self.get_type(var_typedef);
assert_eq!(expr_type_word, var_typeword);
- // Allocate space for a variable
- //
- // TODO: I AM NOT CONVINCED that this is necessary,
- // since our values are all immutable! We might be
- // able to just store the result value word of an
- // expression directly into our scope block and not
- // actually explicitly allocate local vars.
- // But glslang does it this way so for now we follow
- // its example.
- /*
- let var_addr =
- self.b
- .variable(var_typeword, None, spirv::StorageClass::Function, None);
- // Save the result of the expression to the var.
- self.b.store(var_addr, value_word, None, [])?;
- */
// TODO: For now, we don't actually implement any
// pattern matching.
match pattern {
@@ 755,70 711,6 @@ impl CContext {
} else {
unreachable!("Function type is not TypeDef::Function")
}
-
- /*
- let ftype = self.add_type(&verify::TypeDef::Function(
- vec![],
- Box::new(verify::TypeDef::Unit),
- ));
- let void = self.add_type(&verify::TypeDef::Unit);
-
- // Actually make our stub functions
- let v_word = self.b.begin_function(
- void,
- None,
- spirv::FunctionControl::DONT_INLINE | spirv::FunctionControl::CONST,
- ftype,
- )?;
- self.b.begin_basic_block(None)?;
- self.b.ret()?;
- self.b.end_function()?;
-
- let f_word = self.b.begin_function(
- void,
- None,
- spirv::FunctionControl::DONT_INLINE | spirv::FunctionControl::CONST,
- ftype,
- )?;
- self.b.begin_basic_block(None)?;
- self.b.ret()?;
- self.b.end_function()?;
-
-
- // Compile arguments
- let param_words: Result<Vec<(spirv::Word, spirv::Word)>, _> = params
- .clone()
- .iter()
- .map(|param| self.compile_expr(param, ctx))
- .collect();
- let param_words = param_words?;
- let param_words: Vec<spirv::Word> = param_words
- .into_iter()
- .map(|(value_word, _type_word)| value_word)
- .collect();
- // Look up function word
- // ...which requires having compiled the function first. :|
- // TODO: Fix! Somehow... If it isn't, this will panic
- // with variable not found.
- let binding = *self.lookup_var(&fname);
- // Get the function's return type. We have to fetch this
- // from the VContext, since we can't really dig it back
- // out of the SPIR-V.
- let functiondef = ctx
- .functions
- .get(fname)
- .expect("Function does not exist for funcall");
- if let verify::TypeDef::Function(ref _params, ref rettype) = functiondef.functiontype {
- // TODO: Tail call optimization would go here if it went anywhere.
- let rettype_word = self.get_type(rettype);
- let value_word =
- self.b
- .function_call(rettype_word, None, binding.address, param_words)?;
- (value_word, rettype_word)
- } else {
- unreachable!("Function type is not TypeDef::Function")
- }
- */
}
/// Okay, so SPIR-V is a bit persnickity about entry points.
@@ 856,70 748,6 @@ impl CContext {
}
Ok(())
-
- /*
- let frag_name = "_fragment_entry";
- self.b.name(f_word, frag_name);
- self.b
- .entry_point(spirv::ExecutionModel::Vertex, v_word, vert_name, []);
-
- let ftype = self.add_type(&verify::TypeDef::Function(
- vec![],
- Box::new(verify::TypeDef::Unit),
- ));
- let void = self.add_type(&verify::TypeDef::Unit);
-
- // Actually make our stub functions
- let v_word = self.b.begin_function(
- void,
- None,
- spirv::FunctionControl::DONT_INLINE | spirv::FunctionControl::CONST,
- ftype,
- )?;
- self.b.begin_basic_block(None)?;
- self.b.ret()?;
- self.b.end_function()?;
-
- let f_word = self.b.begin_function(
- void,
- None,
- spirv::FunctionControl::DONT_INLINE | spirv::FunctionControl::CONST,
- ftype,
- )?;
- self.b.begin_basic_block(None)?;
- self.b.ret()?;
- self.b.end_function()?;
-
- // We're allowed to reuse the same function as different
- // entry points, so I guess we'll just do that for now
- let vert_name = "_vertex_entry";
- let frag_name = "_fragment_entry";
- self.b.name(v_word, vert_name);
- self.b.name(f_word, frag_name);
- self.b
- .entry_point(spirv::ExecutionModel::Vertex, v_word, vert_name, []);
- self.b
- .entry_point(spirv::ExecutionModel::Fragment, f_word, frag_name, []);
- // TODO: Heck, what the heck to do with this??
- // Well, GLSL uses OriginUpperLeft, so let's do that for now.
- self.b
- .execution_mode(f_word, spirv::ExecutionMode::OriginUpperLeft, []);
-
- Ok(())
- */
- /*
- // If this function is an entry point we declare it such.
- // TODO: This is a little jank but works.
- if def.decl.name == "vertex" {
- // Now if the function is an entry point we need to also add
- // global variables that form the inputs to it...
- self.b
- .entry_point(spirv::ExecutionModel::Vertex, f_word, "vertex", []);
- } else if def.decl.name == "fragment" {
- self.b
- .entry_point(spirv::ExecutionModel::Fragment, f_word, "vertex", []);
- }
- */
}
/// Returns the generated output instructions.