mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Stop using the old Typifier in the backends
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
pub use features::Features;
|
||||
|
||||
use crate::{
|
||||
proc::{EntryPointIndex, NameKey, Namer, ResolveContext, Typifier, TypifyError},
|
||||
proc::{EntryPointIndex, NameKey, Namer, TypeResolution, TypifyError},
|
||||
valid::{FunctionInfo, ModuleInfo},
|
||||
Arena, ArraySize, BinaryOperator, Binding, BuiltIn, Bytes, ConservativeDepth, Constant,
|
||||
ConstantInner, DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle,
|
||||
@@ -185,18 +185,16 @@ enum FunctionType {
|
||||
}
|
||||
|
||||
/// Helper structure that stores data needed when writing the function
|
||||
struct FunctionCtx<'a, 'b> {
|
||||
struct FunctionCtx<'a> {
|
||||
/// The current function being written
|
||||
func: FunctionType,
|
||||
/// Analysis about the function
|
||||
info: &'a FunctionInfo,
|
||||
/// The expression arena of the current function being written
|
||||
expressions: &'a Arena<Expression>,
|
||||
/// A typifier that has already resolved all expressions in the function being written
|
||||
typifier: &'b Typifier,
|
||||
}
|
||||
|
||||
impl<'a, 'b> FunctionCtx<'a, 'b> {
|
||||
impl<'a> FunctionCtx<'a> {
|
||||
/// Helper method that generates a [`NameKey`](crate::proc::NameKey) for a local in the current function
|
||||
fn name_key(&self, local: Handle<LocalVariable>) -> NameKey {
|
||||
match self.func {
|
||||
@@ -855,26 +853,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
info: &FunctionInfo,
|
||||
name: &str,
|
||||
) -> BackendResult {
|
||||
// Create a new typifier and resolve all types for the current function
|
||||
let mut typifier = Typifier::new();
|
||||
typifier.resolve_all(
|
||||
&func.expressions,
|
||||
&self.module.types,
|
||||
&ResolveContext {
|
||||
constants: &self.module.constants,
|
||||
global_vars: &self.module.global_variables,
|
||||
local_vars: &func.local_variables,
|
||||
functions: &self.module.functions,
|
||||
arguments: &func.arguments,
|
||||
},
|
||||
)?;
|
||||
|
||||
// Create a function context for the function being written
|
||||
let ctx = FunctionCtx {
|
||||
func: ty,
|
||||
info,
|
||||
expressions: &func.expressions,
|
||||
typifier: &typifier,
|
||||
};
|
||||
|
||||
self.cached_expressions.clear();
|
||||
@@ -1166,7 +1149,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
fn write_stmt(
|
||||
&mut self,
|
||||
sta: &Statement,
|
||||
ctx: &FunctionCtx<'_, '_>,
|
||||
ctx: &FunctionCtx<'_>,
|
||||
indent: usize,
|
||||
) -> BackendResult {
|
||||
match *sta {
|
||||
@@ -1176,17 +1159,19 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
let min_ref_count = ctx.expressions[handle].bake_ref_count();
|
||||
if min_ref_count <= ctx.info[handle].ref_count {
|
||||
write!(self.out, "{}", INDENT.repeat(indent))?;
|
||||
match ctx.typifier.get_handle(handle) {
|
||||
Ok(ty_handle) => match self.module.types[ty_handle].inner {
|
||||
TypeInner::Struct { .. } => {
|
||||
let ty_name = &self.names[&NameKey::Type(ty_handle)];
|
||||
write!(self.out, "{}", ty_name)?;
|
||||
match ctx.info[handle].ty {
|
||||
TypeResolution::Handle(ty_handle) => {
|
||||
match self.module.types[ty_handle].inner {
|
||||
TypeInner::Struct { .. } => {
|
||||
let ty_name = &self.names[&NameKey::Type(ty_handle)];
|
||||
write!(self.out, "{}", ty_name)?;
|
||||
}
|
||||
_ => {
|
||||
self.write_type(ty_handle)?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
self.write_type(ty_handle)?;
|
||||
}
|
||||
},
|
||||
Err(inner) => {
|
||||
}
|
||||
TypeResolution::Value(ref inner) => {
|
||||
self.write_value_type(inner)?;
|
||||
}
|
||||
}
|
||||
@@ -1413,7 +1398,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
} => {
|
||||
write!(self.out, "{}", INDENT.repeat(indent))?;
|
||||
// This will only panic if the module is invalid
|
||||
let dim = match *ctx.typifier.get(image, &self.module.types) {
|
||||
let dim = match *ctx.info[image].ty.inner_with(&self.module.types) {
|
||||
TypeInner::Image { dim, .. } => dim,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -1453,7 +1438,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
///
|
||||
/// # Notes
|
||||
/// Doesn't add any newlines or leading/trailing spaces
|
||||
fn write_expr(&mut self, expr: Handle<Expression>, ctx: &FunctionCtx<'_, '_>) -> BackendResult {
|
||||
fn write_expr(&mut self, expr: Handle<Expression>, ctx: &FunctionCtx<'_>) -> BackendResult {
|
||||
if let Some(name) = self.cached_expressions.get(&expr) {
|
||||
write!(self.out, "{}", name)?;
|
||||
return Ok(());
|
||||
@@ -1472,13 +1457,14 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
Expression::AccessIndex { base, index } => {
|
||||
self.write_expr(base, ctx)?;
|
||||
|
||||
let mut resolved = ctx.typifier.get(base, &self.module.types);
|
||||
let base_ty_res = &ctx.info[base].ty;
|
||||
let mut resolved = base_ty_res.inner_with(&self.module.types);
|
||||
let base_ty_handle = match *resolved {
|
||||
TypeInner::Pointer { base, class: _ } => {
|
||||
resolved = &self.module.types[base].inner;
|
||||
Ok(base)
|
||||
Some(base)
|
||||
}
|
||||
_ => ctx.typifier.get_handle(base),
|
||||
_ => base_ty_res.handle(),
|
||||
};
|
||||
|
||||
match *resolved {
|
||||
@@ -1576,7 +1562,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
|
||||
// We need to get the coordinates vector size to later build a vector that's `size + 1`
|
||||
// if `depth_ref` is some, if it isn't a vector we panic as that's not a valid expression
|
||||
let size = match *ctx.typifier.get(coordinate, &self.module.types) {
|
||||
let size = match *ctx.info[coordinate].ty.inner_with(&self.module.types) {
|
||||
TypeInner::Vector { size, .. } => size,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@@ -1652,7 +1638,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
index,
|
||||
} => {
|
||||
// This will only panic if the module is invalid
|
||||
let (dim, class) = match *ctx.typifier.get(image, &self.module.types) {
|
||||
let (dim, class) = match *ctx.info[image].ty.inner_with(&self.module.types) {
|
||||
TypeInner::Image {
|
||||
dim,
|
||||
arrayed: _,
|
||||
@@ -1685,7 +1671,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// - textureSamples/imageSamples
|
||||
Expression::ImageQuery { image, query } => {
|
||||
// This will only panic if the module is invalid
|
||||
let (dim, class) = match *ctx.typifier.get(image, &self.module.types) {
|
||||
let (dim, class) = match *ctx.info[image].ty.inner_with(&self.module.types) {
|
||||
TypeInner::Image {
|
||||
dim,
|
||||
arrayed: _,
|
||||
@@ -1759,25 +1745,26 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
"({} ",
|
||||
match op {
|
||||
UnaryOperator::Negate => "-",
|
||||
UnaryOperator::Not => match *ctx.typifier.get(expr, &self.module.types) {
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
..
|
||||
} => "!",
|
||||
ref other =>
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot apply not to type {:?}",
|
||||
other
|
||||
))),
|
||||
},
|
||||
UnaryOperator::Not =>
|
||||
match *ctx.info[expr].ty.inner_with(&self.module.types) {
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
..
|
||||
} => "!",
|
||||
ref other =>
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot apply not to type {:?}",
|
||||
other
|
||||
))),
|
||||
},
|
||||
}
|
||||
)?;
|
||||
|
||||
@@ -1793,8 +1780,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Holds `Some(function_name)` if the binary operation is
|
||||
// implemented as a function call
|
||||
let function = if let (&TypeInner::Vector { .. }, &TypeInner::Vector { .. }) = (
|
||||
ctx.typifier.get(left, &self.module.types),
|
||||
ctx.typifier.get(right, &self.module.types),
|
||||
ctx.info[left].ty.inner_with(&self.module.types),
|
||||
ctx.info[right].ty.inner_with(&self.module.types),
|
||||
) {
|
||||
match op {
|
||||
BinaryOperator::Less => Some("lessThan"),
|
||||
@@ -1979,7 +1966,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
kind,
|
||||
convert,
|
||||
} => {
|
||||
let inner = ctx.typifier.get(expr, &self.module.types);
|
||||
let inner = ctx.info[expr].ty.inner_with(&self.module.types);
|
||||
if convert {
|
||||
// this is similar to `write_type`, but with the target kind
|
||||
match *inner {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use super::{keywords::RESERVED, Error, LocationMode, Options, TranslationInfo};
|
||||
use crate::{
|
||||
arena::Handle,
|
||||
proc::{EntryPointIndex, NameKey, Namer, ResolveContext, Typifier},
|
||||
proc::{EntryPointIndex, NameKey, Namer, TypeResolution},
|
||||
valid::{FunctionInfo, GlobalUse, ModuleInfo},
|
||||
FastHashMap,
|
||||
};
|
||||
@@ -68,7 +68,6 @@ pub struct Writer<W> {
|
||||
out: W,
|
||||
names: FastHashMap<NameKey, String>,
|
||||
named_expressions: BitSet,
|
||||
typifier: Typifier,
|
||||
namer: Namer,
|
||||
#[cfg(test)]
|
||||
put_expression_stack_pointers: crate::FastHashSet<*const ()>,
|
||||
@@ -138,13 +137,19 @@ enum FunctionOrigin {
|
||||
struct ExpressionContext<'a> {
|
||||
function: &'a crate::Function,
|
||||
origin: FunctionOrigin,
|
||||
info: &'a FunctionInfo,
|
||||
module: &'a crate::Module,
|
||||
mod_info: &'a ModuleInfo,
|
||||
}
|
||||
|
||||
impl<'a> ExpressionContext<'a> {
|
||||
fn resolve_type(&self, handle: Handle<crate::Expression>) -> &'a crate::TypeInner {
|
||||
self.info[handle].ty.inner_with(&self.module.types)
|
||||
}
|
||||
}
|
||||
|
||||
struct StatementContext<'a> {
|
||||
expression: ExpressionContext<'a>,
|
||||
fun_info: &'a FunctionInfo,
|
||||
mod_info: &'a ModuleInfo,
|
||||
result_struct: Option<&'a str>,
|
||||
}
|
||||
|
||||
@@ -155,7 +160,6 @@ impl<W: Write> Writer<W> {
|
||||
out,
|
||||
names: FastHashMap::default(),
|
||||
named_expressions: BitSet::new(),
|
||||
typifier: Typifier::new(),
|
||||
namer: Namer::default(),
|
||||
#[cfg(test)]
|
||||
put_expression_stack_pointers: Default::default(),
|
||||
@@ -226,13 +230,14 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
crate::Expression::AccessIndex { base, index } => {
|
||||
self.put_expression(base, context)?;
|
||||
let mut resolved = self.typifier.get(base, &context.module.types);
|
||||
let base_res = &context.info[base].ty;
|
||||
let mut resolved = base_res.inner_with(&context.module.types);
|
||||
let base_ty_handle = match *resolved {
|
||||
crate::TypeInner::Pointer { base, class: _ } => {
|
||||
resolved = &context.module.types[base].inner;
|
||||
Ok(base)
|
||||
Some(base)
|
||||
}
|
||||
_ => self.typifier.get_handle(base),
|
||||
_ => base_res.handle(),
|
||||
};
|
||||
match *resolved {
|
||||
crate::TypeInner::Struct { .. } => {
|
||||
@@ -410,7 +415,7 @@ impl<W: Write> Writer<W> {
|
||||
crate::ImageQuery::Size { level } => {
|
||||
//Note: MSL only has separate width/height/depth queries,
|
||||
// so compose the result of them.
|
||||
let dim = match *self.typifier.get(image, &context.module.types) {
|
||||
let dim = match *context.resolve_type(image) {
|
||||
crate::TypeInner::Image { dim, .. } => dim,
|
||||
ref other => unreachable!("Unexpected type {:?}", other),
|
||||
};
|
||||
@@ -488,9 +493,8 @@ impl<W: Write> Writer<W> {
|
||||
crate::BinaryOperator::ShiftLeft => "<<",
|
||||
crate::BinaryOperator::ShiftRight => ">>",
|
||||
};
|
||||
let kind = self
|
||||
.typifier
|
||||
.get(left, &context.module.types)
|
||||
let kind = context
|
||||
.resolve_type(left)
|
||||
.scalar_kind()
|
||||
.ok_or(Error::UnsupportedBinaryOp(op))?;
|
||||
if op == crate::BinaryOperator::Modulo && kind == crate::ScalarKind::Float {
|
||||
@@ -615,7 +619,7 @@ impl<W: Write> Writer<W> {
|
||||
convert,
|
||||
} => {
|
||||
let scalar = scalar_kind_string(kind);
|
||||
let size = match *self.typifier.get(expr, &context.module.types) {
|
||||
let size = match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Scalar { .. } => "",
|
||||
crate::TypeInner::Vector { size, .. } => vector_size_string(size),
|
||||
_ => return Err(Error::Validation),
|
||||
@@ -627,37 +631,39 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
// has to be a named expression
|
||||
crate::Expression::Call(_) => unreachable!(),
|
||||
crate::Expression::ArrayLength(expr) => {
|
||||
match *self.typifier.get(expr, &context.module.types) {
|
||||
crate::TypeInner::Array {
|
||||
size: crate::ArraySize::Constant(const_handle),
|
||||
..
|
||||
} => {
|
||||
let size_str = &self.names[&NameKey::Constant(const_handle)];
|
||||
write!(self.out, "{}", size_str)?;
|
||||
}
|
||||
crate::TypeInner::Array { .. } => {
|
||||
return Err(Error::FeatureNotImplemented(
|
||||
"dynamic array size".to_string(),
|
||||
))
|
||||
}
|
||||
_ => return Err(Error::Validation),
|
||||
crate::Expression::ArrayLength(expr) => match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Array {
|
||||
size: crate::ArraySize::Constant(const_handle),
|
||||
..
|
||||
} => {
|
||||
let size_str = &self.names[&NameKey::Constant(const_handle)];
|
||||
write!(self.out, "{}", size_str)?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Array { .. } => {
|
||||
return Err(Error::FeatureNotImplemented(
|
||||
"dynamic array size".to_string(),
|
||||
))
|
||||
}
|
||||
_ => return Err(Error::Validation),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_baking_expression(&mut self, handle: Handle<crate::Expression>) -> Result<(), Error> {
|
||||
match self.typifier.get_handle(handle) {
|
||||
Ok(ty_handle) => {
|
||||
fn start_baking_expression(
|
||||
&mut self,
|
||||
handle: Handle<crate::Expression>,
|
||||
context: &ExpressionContext,
|
||||
) -> Result<(), Error> {
|
||||
match context.info[handle].ty {
|
||||
TypeResolution::Handle(ty_handle) => {
|
||||
let ty_name = &self.names[&NameKey::Type(ty_handle)];
|
||||
write!(self.out, "{}", ty_name)?;
|
||||
}
|
||||
Err(&crate::TypeInner::Scalar { kind, .. }) => {
|
||||
TypeResolution::Value(crate::TypeInner::Scalar { kind, .. }) => {
|
||||
write!(self.out, "{}", scalar_kind_string(kind))?;
|
||||
}
|
||||
Err(&crate::TypeInner::Vector { size, kind, .. }) => {
|
||||
TypeResolution::Value(crate::TypeInner::Vector { size, kind, .. }) => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}::{}{}",
|
||||
@@ -666,7 +672,7 @@ impl<W: Write> Writer<W> {
|
||||
vector_size_string(size)
|
||||
)?;
|
||||
}
|
||||
Err(other) => {
|
||||
TypeResolution::Value(ref other) => {
|
||||
log::error!("Type {:?} isn't a known local", other);
|
||||
return Err(Error::FeatureNotImplemented("weird local type".to_string()));
|
||||
}
|
||||
@@ -690,9 +696,9 @@ impl<W: Write> Writer<W> {
|
||||
for handle in range.clone() {
|
||||
let min_ref_count =
|
||||
context.expression.function.expressions[handle].bake_ref_count();
|
||||
if min_ref_count <= context.fun_info[handle].ref_count {
|
||||
if min_ref_count <= context.expression.info[handle].ref_count {
|
||||
write!(self.out, "{}", level)?;
|
||||
self.start_baking_expression(handle)?;
|
||||
self.start_baking_expression(handle, &context.expression)?;
|
||||
self.put_expression(handle, &context.expression)?;
|
||||
writeln!(self.out, ";")?;
|
||||
self.named_expressions.insert(handle.index());
|
||||
@@ -843,7 +849,7 @@ impl<W: Write> Writer<W> {
|
||||
} => {
|
||||
write!(self.out, "{}", level)?;
|
||||
if let Some(expr) = result {
|
||||
self.start_baking_expression(expr)?;
|
||||
self.start_baking_expression(expr, &context.expression)?;
|
||||
self.named_expressions.insert(expr.index());
|
||||
}
|
||||
let fun_name = &self.names[&NameKey::Function(function)];
|
||||
@@ -857,7 +863,7 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
// follow-up with any global resources used
|
||||
let mut separate = !arguments.is_empty();
|
||||
let fun_info = &context.expression.mod_info[function];
|
||||
let fun_info = &context.mod_info[function];
|
||||
for (handle, var) in context.expression.module.global_variables.iter() {
|
||||
if !fun_info[handle].is_empty() && var.class.needs_pass_through() {
|
||||
let name = &self.names[&NameKey::GlobalVariable(handle)];
|
||||
@@ -1109,18 +1115,6 @@ impl<W: Write> Writer<W> {
|
||||
) -> Result<TranslationInfo, Error> {
|
||||
let mut pass_through_globals = Vec::new();
|
||||
for (fun_handle, fun) in module.functions.iter() {
|
||||
self.typifier.resolve_all(
|
||||
&fun.expressions,
|
||||
&module.types,
|
||||
&ResolveContext {
|
||||
constants: &module.constants,
|
||||
global_vars: &module.global_variables,
|
||||
local_vars: &fun.local_variables,
|
||||
functions: &module.functions,
|
||||
arguments: &fun.arguments,
|
||||
},
|
||||
)?;
|
||||
|
||||
let fun_info = &mod_info[fun_handle];
|
||||
pass_through_globals.clear();
|
||||
for (handle, var) in module.global_variables.iter() {
|
||||
@@ -1176,10 +1170,10 @@ impl<W: Write> Writer<W> {
|
||||
expression: ExpressionContext {
|
||||
function: fun,
|
||||
origin: FunctionOrigin::Handle(fun_handle),
|
||||
info: fun_info,
|
||||
module,
|
||||
mod_info,
|
||||
},
|
||||
fun_info,
|
||||
mod_info,
|
||||
result_struct: None,
|
||||
};
|
||||
self.named_expressions.clear();
|
||||
@@ -1215,18 +1209,6 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
}
|
||||
|
||||
self.typifier.resolve_all(
|
||||
&fun.expressions,
|
||||
&module.types,
|
||||
&ResolveContext {
|
||||
constants: &module.constants,
|
||||
global_vars: &module.global_variables,
|
||||
local_vars: &fun.local_variables,
|
||||
functions: &module.functions,
|
||||
arguments: &fun.arguments,
|
||||
},
|
||||
)?;
|
||||
|
||||
let fun_name = &self.names[&NameKey::EntryPoint(ep_index as _)];
|
||||
info.entry_point_names.push(Ok(fun_name.clone()));
|
||||
|
||||
@@ -1468,10 +1450,10 @@ impl<W: Write> Writer<W> {
|
||||
expression: ExpressionContext {
|
||||
function: fun,
|
||||
origin: FunctionOrigin::EntryPoint(ep_index as _),
|
||||
info: fun_info,
|
||||
module,
|
||||
mod_info,
|
||||
},
|
||||
fun_info,
|
||||
mod_info,
|
||||
result_struct: Some(&stage_out_name),
|
||||
};
|
||||
self.named_expressions.clear();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use super::{Instruction, LogicalLayout, Options, PhysicalLayout, WriterFlags};
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
proc::{Layouter, ResolveContext, Typifier, TypifyError},
|
||||
proc::{Layouter, TypeResolution},
|
||||
valid::{FunctionInfo, ModuleInfo},
|
||||
};
|
||||
use spirv::Word;
|
||||
@@ -19,8 +19,6 @@ pub enum Error {
|
||||
MissingCapabilities(Vec<spirv::Capability>),
|
||||
#[error("unimplemented {0}")]
|
||||
FeatureNotImplemented(&'static str),
|
||||
#[error(transparent)]
|
||||
Resolve(#[from] TypifyError),
|
||||
}
|
||||
|
||||
struct Block {
|
||||
@@ -263,7 +261,6 @@ pub struct Writer {
|
||||
struct_type_handles: crate::FastHashMap<Handle<crate::Type>, crate::StorageAccess>,
|
||||
gl450_ext_inst_id: Word,
|
||||
layouter: Layouter,
|
||||
typifier: Typifier,
|
||||
temp_chain: Vec<Word>,
|
||||
}
|
||||
|
||||
@@ -295,7 +292,6 @@ impl Writer {
|
||||
struct_type_handles: crate::FastHashMap::default(),
|
||||
gl450_ext_inst_id,
|
||||
layouter: Layouter::default(),
|
||||
typifier: Typifier::new(),
|
||||
temp_chain: Vec::new(),
|
||||
})
|
||||
}
|
||||
@@ -378,18 +374,6 @@ impl Writer {
|
||||
) -> Result<Word, Error> {
|
||||
let mut function = Function::default();
|
||||
|
||||
self.typifier.resolve_all(
|
||||
&ir_function.expressions,
|
||||
&ir_module.types,
|
||||
&ResolveContext {
|
||||
constants: &ir_module.constants,
|
||||
global_vars: &ir_module.global_variables,
|
||||
local_vars: &ir_function.local_variables,
|
||||
functions: &ir_module.functions,
|
||||
arguments: &ir_function.arguments,
|
||||
},
|
||||
)?;
|
||||
|
||||
for (handle, variable) in ir_function.local_variables.iter() {
|
||||
let id = self.generate_id();
|
||||
|
||||
@@ -559,6 +543,7 @@ impl Writer {
|
||||
self.cache_expression_value(
|
||||
ir_module,
|
||||
ir_function,
|
||||
info,
|
||||
handle,
|
||||
&mut prelude,
|
||||
&mut function,
|
||||
@@ -573,6 +558,7 @@ impl Writer {
|
||||
&ir_function.body,
|
||||
ir_module,
|
||||
ir_function,
|
||||
info,
|
||||
&mut function,
|
||||
None,
|
||||
LoopContext::default(),
|
||||
@@ -1209,6 +1195,7 @@ impl Writer {
|
||||
fn write_texture_coordinates(
|
||||
&mut self,
|
||||
ir_module: &crate::Module,
|
||||
fun_info: &FunctionInfo,
|
||||
coordinates: Handle<crate::Expression>,
|
||||
array_index: Option<Handle<crate::Expression>>,
|
||||
block: &mut Block,
|
||||
@@ -1227,7 +1214,7 @@ impl Writer {
|
||||
)?;
|
||||
|
||||
let mut constituent_ids = [0u32; 4];
|
||||
let size = match *self.typifier.get(coordinates, &ir_module.types) {
|
||||
let size = match *fun_info[coordinates].ty.inner_with(&ir_module.types) {
|
||||
crate::TypeInner::Scalar { .. } => {
|
||||
constituent_ids[0] = coordinate_id;
|
||||
crate::VectorSize::Bi
|
||||
@@ -1291,13 +1278,16 @@ impl Writer {
|
||||
&mut self,
|
||||
ir_module: &'a crate::Module,
|
||||
ir_function: &crate::Function,
|
||||
fun_info: &FunctionInfo,
|
||||
expr_handle: Handle<crate::Expression>,
|
||||
block: &mut Block,
|
||||
function: &mut Function,
|
||||
) -> Result<(), Error> {
|
||||
let result_lookup_ty = match self.typifier.get_handle(expr_handle) {
|
||||
Ok(ty_handle) => LookupType::Handle(ty_handle),
|
||||
Err(inner) => LookupType::Local(self.physical_layout.make_local(inner).unwrap()),
|
||||
let result_lookup_ty = match fun_info[expr_handle].ty {
|
||||
TypeResolution::Handle(ty_handle) => LookupType::Handle(ty_handle),
|
||||
TypeResolution::Value(ref inner) => {
|
||||
LookupType::Local(self.physical_layout.make_local(inner).unwrap())
|
||||
}
|
||||
};
|
||||
let result_type_id = self.get_type_id(&ir_module.types, result_lookup_ty)?;
|
||||
|
||||
@@ -1313,7 +1303,7 @@ impl Writer {
|
||||
0
|
||||
} else {
|
||||
let index_id = self.cached[index];
|
||||
match *self.typifier.get(base, &ir_module.types) {
|
||||
match *fun_info[base].ty.inner_with(&ir_module.types) {
|
||||
crate::TypeInner::Vector { .. } => {
|
||||
let id = self.generate_id();
|
||||
let base_id = self.cached[base];
|
||||
@@ -1343,7 +1333,7 @@ impl Writer {
|
||||
if base_is_var {
|
||||
0
|
||||
} else {
|
||||
match *self.typifier.get(base, &ir_module.types) {
|
||||
match *fun_info[base].ty.inner_with(&ir_module.types) {
|
||||
crate::TypeInner::Vector { .. }
|
||||
| crate::TypeInner::Matrix { .. }
|
||||
| crate::TypeInner::Array { .. }
|
||||
@@ -1382,7 +1372,7 @@ impl Writer {
|
||||
crate::Expression::Unary { op, expr } => {
|
||||
let id = self.generate_id();
|
||||
let expr_id = self.cached[expr];
|
||||
let expr_ty_inner = self.typifier.get(expr, &ir_module.types);
|
||||
let expr_ty_inner = fun_info[expr].ty.inner_with(&ir_module.types);
|
||||
|
||||
let spirv_op = match op {
|
||||
crate::UnaryOperator::Negate => match expr_ty_inner.scalar_kind() {
|
||||
@@ -1407,8 +1397,8 @@ impl Writer {
|
||||
let left_id = self.cached[left];
|
||||
let right_id = self.cached[right];
|
||||
|
||||
let left_ty_inner = self.typifier.get(left, &ir_module.types);
|
||||
let right_ty_inner = self.typifier.get(right, &ir_module.types);
|
||||
let left_ty_inner = fun_info[left].ty.inner_with(&ir_module.types);
|
||||
let right_ty_inner = fun_info[right].ty.inner_with(&ir_module.types);
|
||||
|
||||
let left_dimension = get_dimension(left_ty_inner);
|
||||
let right_dimension = get_dimension(right_ty_inner);
|
||||
@@ -1543,7 +1533,7 @@ impl Writer {
|
||||
}
|
||||
|
||||
let arg0_id = self.cached[arg];
|
||||
let arg_scalar_kind = self.typifier.get(arg, &ir_module.types).scalar_kind();
|
||||
let arg_scalar_kind = fun_info[arg].ty.inner_with(&ir_module.types).scalar_kind();
|
||||
let arg1_id = match arg1 {
|
||||
Some(handle) => self.cached[handle],
|
||||
None => 0,
|
||||
@@ -1672,6 +1662,7 @@ impl Writer {
|
||||
let (pointer_id, _) = self.write_expression_pointer(
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
pointer,
|
||||
block,
|
||||
function,
|
||||
@@ -1694,9 +1685,9 @@ impl Writer {
|
||||
convert,
|
||||
} => {
|
||||
let expr_id = self.cached[expr];
|
||||
let expr_kind = self
|
||||
.typifier
|
||||
.get(expr, &ir_module.types)
|
||||
let expr_kind = fun_info[expr]
|
||||
.ty
|
||||
.inner_with(&ir_module.types)
|
||||
.scalar_kind()
|
||||
.unwrap();
|
||||
|
||||
@@ -1722,12 +1713,17 @@ impl Writer {
|
||||
index,
|
||||
} => {
|
||||
let image_id = self.get_expression_global(ir_function, image);
|
||||
let coordinate_id =
|
||||
self.write_texture_coordinates(ir_module, coordinate, array_index, block)?;
|
||||
let coordinate_id = self.write_texture_coordinates(
|
||||
ir_module,
|
||||
fun_info,
|
||||
coordinate,
|
||||
array_index,
|
||||
block,
|
||||
)?;
|
||||
|
||||
let id = self.generate_id();
|
||||
|
||||
let image_ty = self.typifier.get(image, &ir_module.types);
|
||||
let image_ty = fun_info[image].ty.inner_with(&ir_module.types);
|
||||
let mut instruction = match *image_ty {
|
||||
crate::TypeInner::Image {
|
||||
class: crate::ImageClass::Storage { .. },
|
||||
@@ -1738,7 +1734,7 @@ impl Writer {
|
||||
|
||||
if let Some(index) = index {
|
||||
let index_id = self.cached[index];
|
||||
let image_ops = match *self.typifier.get(image, &ir_module.types) {
|
||||
let image_ops = match *fun_info[image].ty.inner_with(&ir_module.types) {
|
||||
crate::TypeInner::Image {
|
||||
class: crate::ImageClass::Sampled { multi: true, .. },
|
||||
..
|
||||
@@ -1764,7 +1760,7 @@ impl Writer {
|
||||
use super::instructions::SampleLod;
|
||||
// image
|
||||
let image_id = self.get_expression_global(ir_function, image);
|
||||
let image_type = self.typifier.get_handle(image).unwrap();
|
||||
let image_type = fun_info[image].ty.handle().unwrap();
|
||||
|
||||
// OpTypeSampledImage
|
||||
let sampled_image_type_id = self.get_type_id(
|
||||
@@ -1773,8 +1769,13 @@ impl Writer {
|
||||
)?;
|
||||
|
||||
let sampler_id = self.get_expression_global(ir_function, sampler);
|
||||
let coordinate_id =
|
||||
self.write_texture_coordinates(ir_module, coordinate, array_index, block)?;
|
||||
let coordinate_id = self.write_texture_coordinates(
|
||||
ir_module,
|
||||
fun_info,
|
||||
coordinate,
|
||||
array_index,
|
||||
block,
|
||||
)?;
|
||||
|
||||
let sampled_image_id = self.generate_id();
|
||||
block.body.push(Instruction::sampled_image(
|
||||
@@ -1921,13 +1922,16 @@ impl Writer {
|
||||
&mut self,
|
||||
ir_module: &'a crate::Module,
|
||||
ir_function: &crate::Function,
|
||||
fun_info: &FunctionInfo,
|
||||
mut expr_handle: Handle<crate::Expression>,
|
||||
block: &mut Block,
|
||||
function: &mut Function,
|
||||
) -> Result<(Word, spirv::StorageClass), Error> {
|
||||
let result_lookup_ty = match self.typifier.get_handle(expr_handle) {
|
||||
Ok(ty_handle) => LookupType::Handle(ty_handle),
|
||||
Err(inner) => LookupType::Local(self.physical_layout.make_local(inner).unwrap()),
|
||||
let result_lookup_ty = match fun_info[expr_handle].ty {
|
||||
TypeResolution::Handle(ty_handle) => LookupType::Handle(ty_handle),
|
||||
TypeResolution::Value(ref inner) => {
|
||||
LookupType::Local(self.physical_layout.make_local(inner).unwrap())
|
||||
}
|
||||
};
|
||||
let result_type_id = self.get_type_id(&ir_module.types, result_lookup_ty)?;
|
||||
|
||||
@@ -1998,6 +2002,7 @@ impl Writer {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: put most of these into a `BlockContext` structure!
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn write_block(
|
||||
&mut self,
|
||||
@@ -2005,6 +2010,7 @@ impl Writer {
|
||||
statements: &[crate::Statement],
|
||||
ir_module: &crate::Module,
|
||||
ir_function: &crate::Function,
|
||||
fun_info: &FunctionInfo,
|
||||
function: &mut Function,
|
||||
exit_id: Option<Word>,
|
||||
loop_context: LoopContext,
|
||||
@@ -2021,6 +2027,7 @@ impl Writer {
|
||||
self.cache_expression_value(
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
handle,
|
||||
&mut block,
|
||||
function,
|
||||
@@ -2037,6 +2044,7 @@ impl Writer {
|
||||
block_statements,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(merge_id),
|
||||
loop_context,
|
||||
@@ -2083,6 +2091,7 @@ impl Writer {
|
||||
accept,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(merge_id),
|
||||
loop_context,
|
||||
@@ -2094,6 +2103,7 @@ impl Writer {
|
||||
reject,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(merge_id),
|
||||
loop_context,
|
||||
@@ -2143,6 +2153,7 @@ impl Writer {
|
||||
&case.body,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(case_finish_id),
|
||||
LoopContext::default(),
|
||||
@@ -2154,6 +2165,7 @@ impl Writer {
|
||||
default,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(merge_id),
|
||||
LoopContext::default(),
|
||||
@@ -2187,6 +2199,7 @@ impl Writer {
|
||||
body,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(continuing_id),
|
||||
LoopContext {
|
||||
@@ -2200,6 +2213,7 @@ impl Writer {
|
||||
continuing,
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
function,
|
||||
Some(preamble_id),
|
||||
LoopContext {
|
||||
@@ -2263,6 +2277,7 @@ impl Writer {
|
||||
let (pointer_id, _) = self.write_expression_pointer(
|
||||
ir_module,
|
||||
ir_function,
|
||||
fun_info,
|
||||
pointer,
|
||||
&mut block,
|
||||
function,
|
||||
@@ -2282,6 +2297,7 @@ impl Writer {
|
||||
let image_id = self.get_expression_global(ir_function, image);
|
||||
let coordinate_id = self.write_texture_coordinates(
|
||||
ir_module,
|
||||
fun_info,
|
||||
coordinate,
|
||||
array_index,
|
||||
&mut block,
|
||||
|
||||
Reference in New Issue
Block a user