Skip to content

Commit

Permalink
Complete expression/statement support in MSL, refactor conversion met…
Browse files Browse the repository at this point in the history
…hods in WGSL, and remove Statement::Empty
  • Loading branch information
kvark committed Sep 19, 2020
1 parent ca492e4 commit 0651eb8
Show file tree
Hide file tree
Showing 11 changed files with 474 additions and 377 deletions.
16 changes: 11 additions & 5 deletions src/back/glsl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,6 @@ fn write_statement<'a, 'b>(
indent: usize,
) -> Result<String, Error> {
Ok(match sta {
Statement::Empty => String::new(),
Statement::Block(block) => block
.iter()
.map(|sta| write_statement(sta, module, builder, indent))
Expand Down Expand Up @@ -1173,12 +1172,19 @@ fn write_expression<'a, 'b>(
let value_expr = write_expression(&builder.expressions[expr], module, builder)?;

let (source_kind, ty_expr) = match *builder.typifier.get(expr, &module.types) {
TypeInner::Scalar { width, kind } => (
kind,
TypeInner::Scalar {
width,
kind: source_kind,
} => (
source_kind,
Cow::Borrowed(map_scalar(kind, width, builder.manager)?.full),
),
TypeInner::Vector { width, kind, size } => (
kind,
TypeInner::Vector {
width,
kind: source_kind,
size,
} => (
source_kind,
Cow::Owned(format!(
"{}vec{}",
map_scalar(kind, width, builder.manager)?.prefix,
Expand Down
386 changes: 216 additions & 170 deletions src/back/msl.rs

Large diffs are not rendered by default.

149 changes: 87 additions & 62 deletions src/back/spv/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,19 +321,7 @@ impl Writer {
function_type,
));

let mut block = Block::new();
let id = self.generate_id();
block.label = Some(super::instructions::instruction_label(id));
for statement in ir_function.body.iter() {
self.write_function_statement(
ir_module,
ir_function,
&statement,
&mut block,
&mut function,
);
}
function.blocks.push(block);
let id = self.write_block(&ir_function.body, ir_module, ir_function, &mut function);

function.to_words(&mut self.logical_layout.function_definitions);
super::instructions::instruction_function_end()
Expand Down Expand Up @@ -996,74 +984,111 @@ impl Writer {
}
}

fn write_function_statement(
fn write_block(
&mut self,
statements: &[crate::Statement],
ir_module: &crate::Module,
ir_function: &crate::Function,
statement: &crate::Statement,
block: &mut Block,
function: &mut Function,
) {
match statement {
crate::Statement::Return { value } => match ir_function.return_type {
Some(_) => {
let expression = &ir_function.expressions[value.unwrap()];
let (id, ty) = self
.write_expression(ir_module, ir_function, expression, block, function)
) -> spirv::Word {
let mut block = Block::new();
let id = self.generate_id();
block.label = Some(super::instructions::instruction_label(id));

for statement in statements {
match *statement {
crate::Statement::Block(ref ir_block) => {
if !ir_block.is_empty() {
//TODO: link the block with `OpBranch`
self.write_block(ir_block, ir_module, ir_function, function);
}
}
crate::Statement::Return { value } => {
block.termination = Some(match ir_function.return_type {
Some(_) => {
let expression = &ir_function.expressions[value.unwrap()];
let (id, ty) = self
.write_expression(
ir_module,
ir_function,
expression,
&mut block,
function,
)
.unwrap();

let id = match *expression {
crate::Expression::LocalVariable(_) => {
let load_id = self.generate_id();
let value_ty_id = self.get_type_id(
&ir_module.types,
LookupType::Handle(ty.unwrap()),
);
block.body.push(super::instructions::instruction_load(
value_ty_id,
load_id,
id,
None,
));
load_id
}
_ => id,
};
super::instructions::instruction_return_value(id)
}
None => super::instructions::instruction_return(),
});
}
crate::Statement::Store { pointer, value } => {
let pointer_expression = &ir_function.expressions[pointer];
let value_expression = &ir_function.expressions[value];
let (pointer_id, _) = self
.write_expression(
ir_module,
ir_function,
pointer_expression,
&mut block,
function,
)
.unwrap();
let (value_id, value_ty) = self
.write_expression(
ir_module,
ir_function,
value_expression,
&mut block,
function,
)
.unwrap();

let id = match expression {
let value_id = match value_expression {
crate::Expression::LocalVariable(_) => {
let load_id = self.generate_id();
let value_ty_id =
self.get_type_id(&ir_module.types, LookupType::Handle(ty.unwrap()));
let value_ty_id = self.get_type_id(
&ir_module.types,
LookupType::Handle(value_ty.unwrap()),
);
block.body.push(super::instructions::instruction_load(
value_ty_id,
load_id,
id,
value_id,
None,
));
load_id
}
_ => id,
_ => value_id,
};
block.termination = Some(super::instructions::instruction_return_value(id));
}
None => block.termination = Some(super::instructions::instruction_return()),
},
crate::Statement::Store { pointer, value } => {
let pointer_expression = &ir_function.expressions[*pointer];
let value_expression = &ir_function.expressions[*value];
let (pointer_id, _) = self
.write_expression(ir_module, ir_function, pointer_expression, block, function)
.unwrap();
let (value_id, value_ty) = self
.write_expression(ir_module, ir_function, value_expression, block, function)
.unwrap();

let value_id = match value_expression {
crate::Expression::LocalVariable(_) => {
let load_id = self.generate_id();
let value_ty_id = self
.get_type_id(&ir_module.types, LookupType::Handle(value_ty.unwrap()));
block.body.push(super::instructions::instruction_load(
value_ty_id,
load_id,
value_id,
None,
));
load_id
}
_ => value_id,
};

block.body.push(super::instructions::instruction_store(
pointer_id, value_id, None,
));
block.body.push(super::instructions::instruction_store(
pointer_id, value_id, None,
));
}
_ => unimplemented!("{:?}", statement),
}
crate::Statement::Empty => {}
_ => unimplemented!("{:?}", statement),
}

function.blocks.push(block);
id
}

fn write_physical_layout(&mut self) {
Expand Down
3 changes: 1 addition & 2 deletions src/front/glsl/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,7 +726,6 @@ pomelo! {
extra.context.add_local_var(id, exp);
}
match statements.len() {
0 => Statement::Empty,
1 => statements.remove(0),
_ => Statement::Block(statements),
}
Expand Down Expand Up @@ -774,7 +773,7 @@ pomelo! {
statement_list ::= statement_list(mut ss) statement(s) { ss.push(s); ss }

expression_statement ::= Semicolon {
Statement::Empty
Statement::Block(Vec::new())
}
expression_statement ::= expression(mut e) Semicolon {
match e.statements.len() {
Expand Down
116 changes: 116 additions & 0 deletions src/front/wgsl/conv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
use super::Error;

pub fn map_storage_class(word: &str) -> Result<crate::StorageClass, Error<'_>> {
match word {
"in" => Ok(crate::StorageClass::Input),
"out" => Ok(crate::StorageClass::Output),
"uniform" => Ok(crate::StorageClass::Uniform),
"storage_buffer" => Ok(crate::StorageClass::StorageBuffer),
_ => Err(Error::UnknownStorageClass(word)),
}
}

pub fn map_built_in(word: &str) -> Result<crate::BuiltIn, Error<'_>> {
Ok(match word {
// vertex
"position" => crate::BuiltIn::Position,
"vertex_idx" => crate::BuiltIn::VertexIndex,
"instance_idx" => crate::BuiltIn::InstanceIndex,
// fragment
"front_facing" => crate::BuiltIn::FrontFacing,
"frag_coord" => crate::BuiltIn::FragCoord,
"frag_depth" => crate::BuiltIn::FragDepth,
// compute
"global_invocation_id" => crate::BuiltIn::GlobalInvocationId,
"local_invocation_id" => crate::BuiltIn::LocalInvocationId,
"local_invocation_idx" => crate::BuiltIn::LocalInvocationIndex,
_ => return Err(Error::UnknownBuiltin(word)),
})
}

pub fn map_shader_stage(word: &str) -> Result<crate::ShaderStage, Error<'_>> {
match word {
"vertex" => Ok(crate::ShaderStage::Vertex),
"fragment" => Ok(crate::ShaderStage::Fragment),
"compute" => Ok(crate::ShaderStage::Compute),
_ => Err(Error::UnknownShaderStage(word)),
}
}

pub fn map_interpolation(word: &str) -> Result<crate::Interpolation, Error<'_>> {
match word {
"linear" => Ok(crate::Interpolation::Linear),
"flat" => Ok(crate::Interpolation::Flat),
"centroid" => Ok(crate::Interpolation::Centroid),
"sample" => Ok(crate::Interpolation::Sample),
"perspective" => Ok(crate::Interpolation::Perspective),
_ => Err(Error::UnknownDecoration(word)),
}
}

pub fn map_storage_format(word: &str) -> Result<crate::StorageFormat, Error<'_>> {
use crate::StorageFormat as Sf;
Ok(match word {
"r8unorm" => Sf::R8Unorm,
"r8snorm" => Sf::R8Snorm,
"r8uint" => Sf::R8Uint,
"r8sint" => Sf::R8Sint,
"r16uint" => Sf::R16Uint,
"r16sint" => Sf::R16Sint,
"r16float" => Sf::R16Float,
"rg8unorm" => Sf::Rg8Unorm,
"rg8snorm" => Sf::Rg8Snorm,
"rg8uint" => Sf::Rg8Uint,
"rg8sint" => Sf::Rg8Sint,
"r32uint" => Sf::R32Uint,
"r32sint" => Sf::R32Sint,
"r32float" => Sf::R32Float,
"rg16uint" => Sf::Rg16Uint,
"rg16sint" => Sf::Rg16Sint,
"rg16float" => Sf::Rg16Float,
"rgba8unorm" => Sf::Rgba8Unorm,
"rgba8snorm" => Sf::Rgba8Snorm,
"rgba8uint" => Sf::Rgba8Uint,
"rgba8sint" => Sf::Rgba8Sint,
"rgb10a2unorm" => Sf::Rgb10a2Unorm,
"rg11b10float" => Sf::Rg11b10Float,
"rg32uint" => Sf::Rg32Uint,
"rg32sint" => Sf::Rg32Sint,
"rg32float" => Sf::Rg32Float,
"rgba16uint" => Sf::Rgba16Uint,
"rgba16sint" => Sf::Rgba16Sint,
"rgba16float" => Sf::Rgba16Float,
"rgba32uint" => Sf::Rgba32Uint,
"rgba32sint" => Sf::Rgba32Sint,
"rgba32float" => Sf::Rgba32Float,
_ => return Err(Error::UnknownStorageFormat(word)),
})
}

pub fn get_scalar_type(word: &str) -> Option<(crate::ScalarKind, crate::Bytes)> {
match word {
"f32" => Some((crate::ScalarKind::Float, 4)),
"i32" => Some((crate::ScalarKind::Sint, 4)),
"u32" => Some((crate::ScalarKind::Uint, 4)),
_ => None,
}
}

pub fn get_intrinsic(word: &str) -> Option<crate::IntrinsicFunction> {
match word {
"any" => Some(crate::IntrinsicFunction::Any),
"all" => Some(crate::IntrinsicFunction::All),
"is_nan" => Some(crate::IntrinsicFunction::IsNan),
"is_inf" => Some(crate::IntrinsicFunction::IsInf),
"is_normal" => Some(crate::IntrinsicFunction::IsNormal),
_ => None,
}
}
pub fn get_derivative(word: &str) -> Option<crate::DerivativeAxis> {
match word {
"dpdx" => Some(crate::DerivativeAxis::X),
"dpdy" => Some(crate::DerivativeAxis::Y),
"dwidth" => Some(crate::DerivativeAxis::Width),
_ => None,
}
}
Loading

0 comments on commit 0651eb8

Please sign in to comment.