mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Statement for void function call
This commit is contained in:
committed by
Dzmitry Malyshau
parent
f9f41fc9bf
commit
d949d58f7b
@@ -979,11 +979,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// The indentation is only for readability
|
||||
write!(self.out, "{}", INDENT.repeat(indent))?;
|
||||
|
||||
match sta {
|
||||
match *sta {
|
||||
// Blocks are simple we just need to write the block statements between braces
|
||||
// We could also just print the statements but this is more readable and maps more
|
||||
// closely to the IR
|
||||
Statement::Block(block) => {
|
||||
Statement::Block(ref block) => {
|
||||
writeln!(self.out, "{{")?;
|
||||
for sta in block.iter() {
|
||||
// Increase the indentation to help with readability
|
||||
@@ -1001,11 +1001,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// ```
|
||||
Statement::If {
|
||||
condition,
|
||||
accept,
|
||||
reject,
|
||||
ref accept,
|
||||
ref reject,
|
||||
} => {
|
||||
write!(self.out, "if(")?;
|
||||
self.write_expr(*condition, ctx)?;
|
||||
self.write_expr(condition, ctx)?;
|
||||
writeln!(self.out, ") {{")?;
|
||||
|
||||
for sta in accept {
|
||||
@@ -1044,12 +1044,12 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// so that we don't need to print a `break` for it
|
||||
Statement::Switch {
|
||||
selector,
|
||||
cases,
|
||||
default,
|
||||
ref cases,
|
||||
ref default,
|
||||
} => {
|
||||
// Start the switch
|
||||
write!(self.out, "switch(")?;
|
||||
self.write_expr(*selector, ctx)?;
|
||||
self.write_expr(selector, ctx)?;
|
||||
writeln!(self.out, ") {{")?;
|
||||
|
||||
// Write all cases
|
||||
@@ -1091,7 +1091,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// continuing
|
||||
// }
|
||||
// ```
|
||||
Statement::Loop { body, continuing } => {
|
||||
Statement::Loop {
|
||||
ref body,
|
||||
ref continuing,
|
||||
} => {
|
||||
writeln!(self.out, "while(true) {{")?;
|
||||
|
||||
for sta in body.iter().chain(continuing.iter()) {
|
||||
@@ -1111,7 +1114,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Write the expression to be returned if needed
|
||||
if let Some(expr) = value {
|
||||
write!(self.out, " ")?;
|
||||
self.write_expr(*expr, ctx)?;
|
||||
self.write_expr(expr, ctx)?;
|
||||
}
|
||||
writeln!(self.out, ";")?;
|
||||
}
|
||||
@@ -1121,11 +1124,20 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
Statement::Kill => writeln!(self.out, "discard;")?,
|
||||
// Stores in glsl are just variable assignments written as `pointer = value;`
|
||||
Statement::Store { pointer, value } => {
|
||||
self.write_expr(*pointer, ctx)?;
|
||||
self.write_expr(pointer, ctx)?;
|
||||
write!(self.out, " = ")?;
|
||||
self.write_expr(*value, ctx)?;
|
||||
self.write_expr(value, ctx)?;
|
||||
writeln!(self.out, ";")?
|
||||
}
|
||||
// A `Call` is written `name(arguments)` where `arguments` is a comma separated expressions list
|
||||
Statement::Call {
|
||||
function,
|
||||
ref arguments,
|
||||
} => {
|
||||
write!(self.out, "{}(", &self.names[&NameKey::Function(function)])?;
|
||||
self.write_slice(arguments, |this, _, arg| this.write_expr(*arg, ctx))?;
|
||||
write!(self.out, ");")?
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -741,6 +741,15 @@ impl<W: Write> Writer<W> {
|
||||
self.put_expression(value, context)?;
|
||||
writeln!(self.out, ";")?;
|
||||
}
|
||||
crate::Statement::Call {
|
||||
function,
|
||||
ref arguments,
|
||||
} => {
|
||||
let name = &self.names[&NameKey::Function(function)];
|
||||
write!(self.out, "{}", name)?;
|
||||
self.put_call("", arguments, context)?;
|
||||
writeln!(self.out, ";")?;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
||||
@@ -181,7 +181,7 @@ pub struct Writer {
|
||||
debugs: Vec<Instruction>,
|
||||
annotations: Vec<Instruction>,
|
||||
flags: WriterFlags,
|
||||
void_type: Option<u32>,
|
||||
void_type: u32,
|
||||
lookup_type: crate::FastHashMap<LookupType, Word>,
|
||||
lookup_function: crate::FastHashMap<crate::Handle<crate::Function>, Word>,
|
||||
lookup_function_type: crate::FastHashMap<LookupFunctionType, Word>,
|
||||
@@ -209,19 +209,19 @@ impl Writer {
|
||||
Writer {
|
||||
physical_layout: PhysicalLayout::new(header),
|
||||
logical_layout: LogicalLayout::default(),
|
||||
id_count: 0,
|
||||
id_count: 2, // 0 is void type, 1 is the GLSL ext inst
|
||||
capabilities,
|
||||
debugs: vec![],
|
||||
annotations: vec![],
|
||||
flags,
|
||||
void_type: None,
|
||||
void_type: 0,
|
||||
lookup_type: crate::FastHashMap::default(),
|
||||
lookup_function: crate::FastHashMap::default(),
|
||||
lookup_function_type: crate::FastHashMap::default(),
|
||||
lookup_constant: crate::FastHashMap::default(),
|
||||
lookup_global_variable: crate::FastHashMap::default(),
|
||||
struct_type_handles: crate::FastHashMap::default(),
|
||||
gl450_ext_inst_id: 0,
|
||||
gl450_ext_inst_id: 1,
|
||||
layouter: Layouter::default(),
|
||||
typifier: Typifier::new(),
|
||||
}
|
||||
@@ -295,26 +295,6 @@ impl Writer {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_function_return_type(
|
||||
&mut self,
|
||||
ty: Option<crate::Handle<crate::Type>>,
|
||||
arena: &crate::Arena<crate::Type>,
|
||||
) -> Result<Word, Error> {
|
||||
match ty {
|
||||
Some(handle) => self.get_type_id(arena, LookupType::Handle(handle)),
|
||||
None => Ok(match self.void_type {
|
||||
Some(id) => id,
|
||||
None => {
|
||||
let id = self.generate_id();
|
||||
self.void_type = Some(id);
|
||||
super::instructions::instruction_type_void(id)
|
||||
.to_words(&mut self.logical_layout.declarations);
|
||||
id
|
||||
}
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_pointer_id(
|
||||
&mut self,
|
||||
arena: &crate::Arena<crate::Type>,
|
||||
@@ -415,8 +395,10 @@ impl Writer {
|
||||
.insert(handle, LocalVariable { id, instruction });
|
||||
}
|
||||
|
||||
let return_type_id =
|
||||
self.get_function_return_type(ir_function.return_type, &ir_module.types)?;
|
||||
let return_type_id = match ir_function.return_type {
|
||||
Some(handle) => self.get_type_id(&ir_module.types, LookupType::Handle(handle))?,
|
||||
None => self.void_type,
|
||||
};
|
||||
let mut parameter_type_ids = Vec::with_capacity(ir_function.arguments.len());
|
||||
|
||||
for argument in ir_function.arguments.iter() {
|
||||
@@ -1922,6 +1904,10 @@ impl Writer {
|
||||
|
||||
block = Block::new(merge_id);
|
||||
}
|
||||
crate::Statement::Switch { .. } => {
|
||||
log::error!("unimplemented Switch");
|
||||
return Err(Error::FeatureNotImplemented("switch"));
|
||||
}
|
||||
crate::Statement::Loop {
|
||||
ref body,
|
||||
ref continuing,
|
||||
@@ -2007,9 +1993,33 @@ impl Writer {
|
||||
pointer_id, value_id, None,
|
||||
));
|
||||
}
|
||||
_ => {
|
||||
log::error!("unimplemented {:?}", statement);
|
||||
return Err(Error::FeatureNotImplemented("statement"));
|
||||
crate::Statement::Call {
|
||||
function: local_function,
|
||||
ref arguments,
|
||||
} => {
|
||||
let id = self.generate_id();
|
||||
//TODO: avoid heap allocation
|
||||
let mut argument_ids = vec![];
|
||||
|
||||
for argument in arguments {
|
||||
let arg_id = self.write_expression(
|
||||
ir_module,
|
||||
ir_function,
|
||||
*argument,
|
||||
&mut block,
|
||||
function,
|
||||
)?;
|
||||
argument_ids.push(arg_id);
|
||||
}
|
||||
|
||||
block
|
||||
.body
|
||||
.push(super::instructions::instruction_function_call(
|
||||
self.void_type,
|
||||
id,
|
||||
*self.lookup_function.get(&local_function).unwrap(),
|
||||
argument_ids.as_slice(),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2030,7 +2040,8 @@ impl Writer {
|
||||
}
|
||||
|
||||
fn write_logical_layout(&mut self, ir_module: &crate::Module) -> Result<(), Error> {
|
||||
self.gl450_ext_inst_id = self.generate_id();
|
||||
super::instructions::instruction_type_void(self.void_type)
|
||||
.to_words(&mut self.logical_layout.declarations);
|
||||
super::instructions::instruction_ext_inst_import(self.gl450_ext_inst_id, "GLSL.std.450")
|
||||
.to_words(&mut self.logical_layout.ext_inst_imports);
|
||||
|
||||
@@ -2113,9 +2124,9 @@ mod tests {
|
||||
fn test_writer_generate_id() {
|
||||
let mut writer = create_writer();
|
||||
|
||||
assert_eq!(writer.id_count, 0);
|
||||
assert_eq!(writer.id_count, 2);
|
||||
writer.generate_id();
|
||||
assert_eq!(writer.id_count, 1);
|
||||
assert_eq!(writer.id_count, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -2123,7 +2134,7 @@ mod tests {
|
||||
let mut writer = create_writer();
|
||||
assert_eq!(writer.physical_layout.bound, 0);
|
||||
writer.write_physical_layout();
|
||||
assert_eq!(writer.physical_layout.bound, 1);
|
||||
assert_eq!(writer.physical_layout.bound, 3);
|
||||
}
|
||||
|
||||
fn create_writer() -> Writer {
|
||||
|
||||
@@ -802,6 +802,11 @@ pub enum Statement {
|
||||
pointer: Handle<Expression>,
|
||||
value: Handle<Expression>,
|
||||
},
|
||||
/// Calls a function with no return value.
|
||||
Call {
|
||||
function: Handle<Function>,
|
||||
arguments: Vec<Handle<Expression>>,
|
||||
},
|
||||
}
|
||||
|
||||
/// A function argument.
|
||||
|
||||
@@ -203,6 +203,15 @@ where
|
||||
self.visitor.visit_lhs_expr(&self.expressions[left]);
|
||||
self.traverse_expr(value);
|
||||
}
|
||||
S::Call {
|
||||
function,
|
||||
ref arguments,
|
||||
} => {
|
||||
for &argument in arguments {
|
||||
self.traverse_expr(argument);
|
||||
}
|
||||
self.visitor.visit_fun(function);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ pub fn ensure_block_returns(block: &mut crate::Block) {
|
||||
| Some(&mut crate::Statement::Kill) => (),
|
||||
Some(&mut crate::Statement::Loop { .. })
|
||||
| Some(&mut crate::Statement::Store { .. })
|
||||
| Some(&mut crate::Statement::Call { .. })
|
||||
| None => block.push(crate::Statement::Return { value: None }),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user