Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy committed Mar 16, 2023
1 parent 6fcd04e commit 34796aa
Show file tree
Hide file tree
Showing 9 changed files with 759 additions and 758 deletions.
10 changes: 0 additions & 10 deletions src/front/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,6 @@ impl Emitter {
}
}

#[allow(dead_code)]
impl super::ConstantInner {
const fn boolean(value: bool) -> Self {
Self::Scalar {
width: super::BOOL_WIDTH,
value: super::ScalarValue::Bool(value),
}
}
}

/// A table of types for an `Arena<Expression>`.
///
/// A front end can use a `Typifier` to get types for an arena's expressions
Expand Down
1 change: 1 addition & 0 deletions src/front/spv/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ impl<I: Iterator<Item = u32>> super::Frontend<I> {
expressions: &mut fun.expressions,
local_arena: &mut fun.local_variables,
const_arena: &mut module.constants,
const_expressions: &mut module.const_expressions,
type_arena: &module.types,
global_arena: &module.global_variables,
arguments: &fun.arguments,
Expand Down
252 changes: 127 additions & 125 deletions src/front/spv/mod.rs

Large diffs are not rendered by default.

282 changes: 125 additions & 157 deletions src/front/spv/null.rs
Original file line number Diff line number Diff line change
@@ -1,175 +1,143 @@
use super::Error;
use crate::arena::{Arena, Handle, UniqueArena};

const fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner {
crate::ConstantInner::Scalar {
width,
value: match kind {
crate::ScalarKind::Uint => crate::ScalarValue::Uint(0),
crate::ScalarKind::Sint => crate::ScalarValue::Sint(0),
crate::ScalarKind::Float => crate::ScalarValue::Float(0.0),
crate::ScalarKind::Bool => crate::ScalarValue::Bool(false),
},
}
}
// const fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner {
// crate::ConstantInner::Scalar {
// width,
// value: match kind {
// crate::ScalarKind::Uint => crate::ScalarValue::Uint(0),
// crate::ScalarKind::Sint => crate::ScalarValue::Sint(0),
// crate::ScalarKind::Float => crate::ScalarValue::Float(0.0),
// crate::ScalarKind::Bool => crate::ScalarValue::Bool(false),
// },
// }
// }

pub fn generate_null_constant(
ty: Handle<crate::Type>,
type_arena: &UniqueArena<crate::Type>,
constant_arena: &mut Arena<crate::Constant>,
span: crate::Span,
) -> Result<crate::ConstantInner, Error> {
let inner = match type_arena[ty].inner {
crate::TypeInner::Scalar { kind, width } => make_scalar_inner(kind, width),
crate::TypeInner::Vector { size, kind, width } => {
let mut components = Vec::with_capacity(size as usize);
for _ in 0..size as usize {
components.push(constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner: make_scalar_inner(kind, width),
},
span,
));
}
crate::ConstantInner::Composite { ty, components }
}
crate::TypeInner::Matrix {
columns,
rows,
width,
} => {
// If we successfully declared a matrix type, we have declared a vector type for it too.
let vector_ty = type_arena
.get(&crate::Type {
name: None,
inner: crate::TypeInner::Vector {
kind: crate::ScalarKind::Float,
size: rows,
width,
},
})
.unwrap();
let vector_inner = generate_null_constant(vector_ty, type_arena, constant_arena, span)?;
let vector_handle = constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner: vector_inner,
},
span,
);
crate::ConstantInner::Composite {
ty,
components: vec![vector_handle; columns as usize],
}
}
crate::TypeInner::Struct { ref members, .. } => {
let mut components = Vec::with_capacity(members.len());
// copy out the types to avoid borrowing `members`
let member_tys = members.iter().map(|member| member.ty).collect::<Vec<_>>();
for member_ty in member_tys {
let inner = generate_null_constant(member_ty, type_arena, constant_arena, span)?;
components.push(constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner,
},
span,
));
}
crate::ConstantInner::Composite { ty, components }
}
crate::TypeInner::Array {
base,
size: crate::ArraySize::Constant(handle),
..
} => {
let size = constant_arena[handle]
.to_array_length()
.ok_or(Error::InvalidArraySize(handle))?;
let inner = generate_null_constant(base, type_arena, constant_arena, span)?;
let value = constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner,
},
span,
);
crate::ConstantInner::Composite {
ty,
components: vec![value; size as usize],
}
}
ref other => {
log::warn!("null constant type {:?}", other);
return Err(Error::UnsupportedType(ty));
}
};
Ok(inner)
}
// pub fn generate_null_constant(
// ty: Handle<crate::Type>,
// type_arena: &UniqueArena<crate::Type>,
// constant_arena: &mut Arena<crate::Constant>,
// span: crate::Span,
// ) -> Result<crate::ConstantInner, Error> {
// let inner = match type_arena[ty].inner {
// crate::TypeInner::Scalar { kind, width } => make_scalar_inner(kind, width),
// crate::TypeInner::Vector { size, kind, width } => {
// let mut components = Vec::with_capacity(size as usize);
// for _ in 0..size as usize {
// components.push(constant_arena.fetch_or_append(
// crate::Constant {
// name: None,
// specialization: None,
// inner: make_scalar_inner(kind, width),
// },
// span,
// ));
// }
// crate::ConstantInner::Composite { ty, components }
// }
// crate::TypeInner::Matrix {
// columns,
// rows,
// width,
// } => {
// // If we successfully declared a matrix type, we have declared a vector type for it too.
// let vector_ty = type_arena
// .get(&crate::Type {
// name: None,
// inner: crate::TypeInner::Vector {
// kind: crate::ScalarKind::Float,
// size: rows,
// width,
// },
// })
// .unwrap();
// let vector_inner = generate_null_constant(vector_ty, type_arena, constant_arena, span)?;
// let vector_handle = constant_arena.fetch_or_append(
// crate::Constant {
// name: None,
// specialization: None,
// inner: vector_inner,
// },
// span,
// );
// crate::ConstantInner::Composite {
// ty,
// components: vec![vector_handle; columns as usize],
// }
// }
// crate::TypeInner::Struct { ref members, .. } => {
// let mut components = Vec::with_capacity(members.len());
// // copy out the types to avoid borrowing `members`
// let member_tys = members.iter().map(|member| member.ty).collect::<Vec<_>>();
// for member_ty in member_tys {
// let inner = generate_null_constant(member_ty, type_arena, constant_arena, span)?;
// components.push(constant_arena.fetch_or_append(
// crate::Constant {
// name: None,
// specialization: None,
// inner,
// },
// span,
// ));
// }
// crate::ConstantInner::Composite { ty, components }
// }
// crate::TypeInner::Array {
// base,
// size: crate::ArraySize::Constant(handle),
// ..
// } => {
// let size = constant_arena[handle]
// .to_array_length()
// .ok_or(Error::InvalidArraySize(handle))?;
// let inner = generate_null_constant(base, type_arena, constant_arena, span)?;
// let value = constant_arena.fetch_or_append(
// crate::Constant {
// name: None,
// specialization: None,
// inner,
// },
// span,
// );
// crate::ConstantInner::Composite {
// ty,
// components: vec![value; size as usize],
// }
// }
// ref other => {
// log::warn!("null constant type {:?}", other);
// return Err(Error::UnsupportedType(ty));
// }
// };
// Ok(inner)
// }

/// Create a default value for an output built-in.
pub fn generate_default_built_in(
built_in: Option<crate::BuiltIn>,
ty: Handle<crate::Type>,
type_arena: &UniqueArena<crate::Type>,
constant_arena: &mut Arena<crate::Constant>,
const_expressions: &mut Arena<crate::Expression>,
span: crate::Span,
) -> Result<Handle<crate::Constant>, Error> {
let inner = match built_in {
) -> Result<Handle<crate::Expression>, Error> {
let expr = match built_in {
Some(crate::BuiltIn::Position { .. }) => {
let zero = constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner: crate::ConstantInner::Scalar {
value: crate::ScalarValue::Float(0.0),
width: 4,
},
},
span,
);
let one = constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner: crate::ConstantInner::Scalar {
value: crate::ScalarValue::Float(1.0),
width: 4,
},
},
span,
);
crate::ConstantInner::Composite {
let zero = const_expressions
.append(crate::Expression::Literal(crate::Literal::F32(0.0)), span);
let one = const_expressions
.append(crate::Expression::Literal(crate::Literal::F32(1.0)), span);
crate::Expression::Compose {
ty,
components: vec![zero, zero, zero, one],
}
}
Some(crate::BuiltIn::PointSize) => crate::ConstantInner::Scalar {
value: crate::ScalarValue::Float(1.0),
width: 4,
},
Some(crate::BuiltIn::FragDepth) => crate::ConstantInner::Scalar {
value: crate::ScalarValue::Float(0.0),
width: 4,
},
Some(crate::BuiltIn::SampleMask) => crate::ConstantInner::Scalar {
value: crate::ScalarValue::Uint(u64::MAX),
width: 4,
},
//Note: `crate::BuiltIn::ClipDistance` is intentionally left for the default path
_ => generate_null_constant(ty, type_arena, constant_arena, span)?,
Some(crate::BuiltIn::PointSize) => crate::Expression::Literal(crate::Literal::F32(1.0)),
Some(crate::BuiltIn::FragDepth) => crate::Expression::Literal(crate::Literal::F32(0.0)),
Some(crate::BuiltIn::SampleMask) => {
crate::Expression::Literal(crate::Literal::U32(u32::MAX))
}
// Note: `crate::BuiltIn::ClipDistance` is intentionally left for the default path
_ => crate::Expression::New(ty),
};
Ok(constant_arena.fetch_or_append(
crate::Constant {
name: None,
specialization: None,
inner,
},
span,
))
Ok(const_expressions.append(expr, span))
}
Loading

0 comments on commit 34796aa

Please sign in to comment.