Stop using the old Typifier in the backends

This commit is contained in:
Dzmitry Malyshau
2021-03-22 12:02:52 -04:00
parent 970b77abaf
commit d4bc463d50
3 changed files with 153 additions and 168 deletions

View File

@@ -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 {

View File

@@ -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();

View File

@@ -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,