mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-30 18:53:25 +00:00
glsl-out: fixes (#164)
* Fixed not generating wrong op on booleans Correctly handle storage images and sampled images * Fixed comments
This commit is contained in:
parent
447e2483f9
commit
73204d094c
214
src/back/glsl.rs
214
src/back/glsl.rs
@ -2,7 +2,7 @@ use crate::{
|
||||
Arena, ArraySize, BinaryOperator, BuiltIn, Constant, ConstantInner, DerivativeAxis, Expression,
|
||||
FastHashMap, Function, FunctionOrigin, GlobalVariable, Handle, ImageClass, Interpolation,
|
||||
IntrinsicFunction, LocalVariable, MemberOrigin, Module, ScalarKind, ShaderStage, Statement,
|
||||
StorageClass, StructMember, Type, TypeInner, UnaryOperator,
|
||||
StorageAccess, StorageClass, StorageFormat, StructMember, Type, TypeInner, UnaryOperator,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@ -251,9 +251,43 @@ pub fn write<'a>(module: &'a Module, out: &mut impl Write, options: Options) ->
|
||||
})?
|
||||
};
|
||||
|
||||
if let Some(ref binding) = global.binding {
|
||||
if !es {
|
||||
write!(out, "layout({}) ", Binding(binding))?;
|
||||
let storage_format = match module.types[global.ty].inner {
|
||||
TypeInner::Image {
|
||||
class: ImageClass::Storage(format, _),
|
||||
..
|
||||
} => Some(format),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if global.binding.is_some() {
|
||||
write!(out, "layout(")?;
|
||||
|
||||
if let Some(ref binding) = global.binding {
|
||||
if !es {
|
||||
write!(out, "{}", Binding(binding))?;
|
||||
}
|
||||
}
|
||||
|
||||
if storage_format.is_some() && global.binding.is_some() {
|
||||
write!(out, ",")?;
|
||||
}
|
||||
|
||||
if let Some(format) = storage_format {
|
||||
write!(out, "{}", write_format_glsl(format))?;
|
||||
}
|
||||
|
||||
write!(out, ") ")?;
|
||||
}
|
||||
|
||||
if let TypeInner::Image {
|
||||
class: ImageClass::Storage(_, access),
|
||||
..
|
||||
} = module.types[global.ty].inner
|
||||
{
|
||||
if access == StorageAccess::LOAD {
|
||||
write!(out, "readonly ")?;
|
||||
} else if access == StorageAccess::STORE {
|
||||
write!(out, "writeonly ")?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -499,7 +533,7 @@ fn write_statement<'a, 'b>(
|
||||
)?;
|
||||
}
|
||||
|
||||
if fallthrough.is_some() {
|
||||
if fallthrough.is_none() {
|
||||
writeln!(&mut out, "{}break;", "\t".repeat(indent + 2),)?;
|
||||
}
|
||||
}
|
||||
@ -828,7 +862,14 @@ fn write_expression<'a, 'b>(
|
||||
sampler_constructor, coordinate, level_expr
|
||||
)
|
||||
}
|
||||
crate::SampleLevel::Bias(_) => todo!(),
|
||||
crate::SampleLevel::Bias(bias) => {
|
||||
let (bias_expr, _) =
|
||||
write_expression(&builder.expressions[bias], module, builder)?;
|
||||
format!(
|
||||
"texture({},{},{})",
|
||||
sampler_constructor, coordinate, bias_expr
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
let width = 4;
|
||||
@ -843,7 +884,7 @@ fn write_expression<'a, 'b>(
|
||||
Expression::ImageLoad {
|
||||
image,
|
||||
coordinate,
|
||||
index: _,
|
||||
index,
|
||||
} => {
|
||||
let (image_expr, image_ty) =
|
||||
write_expression(&builder.expressions[image], module, builder)?;
|
||||
@ -860,10 +901,6 @@ fn write_expression<'a, 'b>(
|
||||
_ => return Err(Error::Custom(format!("Cannot load {:?}", image_ty))),
|
||||
};
|
||||
|
||||
let ms = match class {
|
||||
crate::ImageClass::Multisampled => true,
|
||||
_ => false,
|
||||
};
|
||||
let size = match coordinate_ty.as_ref() {
|
||||
TypeInner::Vector { size, .. } => *size,
|
||||
_ => {
|
||||
@ -874,25 +911,47 @@ fn write_expression<'a, 'b>(
|
||||
}
|
||||
};
|
||||
|
||||
//TODO: fix this
|
||||
let sampler_constructor = format!(
|
||||
"{}sampler{}{}{}({})",
|
||||
match kind {
|
||||
ScalarKind::Sint => "i",
|
||||
ScalarKind::Uint => "u",
|
||||
ScalarKind::Float => "",
|
||||
_ => return Err(Error::Custom(String::from("Cannot build image of bools",))),
|
||||
},
|
||||
ImageDimension(dim),
|
||||
if ms { "MS" } else { "" },
|
||||
if arrayed { "Array" } else { "" },
|
||||
image_expr,
|
||||
);
|
||||
let expr = match class {
|
||||
ImageClass::Sampled | ImageClass::Multisampled => {
|
||||
let ms = match class {
|
||||
crate::ImageClass::Multisampled => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let expr = if !ms {
|
||||
format!("texture({},{})", sampler_constructor, coordinate_expr)
|
||||
} else {
|
||||
todo!()
|
||||
//TODO: fix this
|
||||
let sampler_constructor = format!(
|
||||
"{}sampler{}{}{}({})",
|
||||
match kind {
|
||||
ScalarKind::Sint => "i",
|
||||
ScalarKind::Uint => "u",
|
||||
ScalarKind::Float => "",
|
||||
_ =>
|
||||
return Err(Error::Custom(String::from(
|
||||
"Cannot build image of bools"
|
||||
))),
|
||||
},
|
||||
ImageDimension(dim),
|
||||
if ms { "MS" } else { "" },
|
||||
if arrayed { "Array" } else { "" },
|
||||
image_expr,
|
||||
);
|
||||
|
||||
if !ms {
|
||||
format!("texelFetch({},{})", sampler_constructor, coordinate_expr)
|
||||
} else {
|
||||
let (index_expr, _) =
|
||||
write_expression(&builder.expressions[index], module, builder)?;
|
||||
|
||||
format!(
|
||||
"texelFetch({},{},{})",
|
||||
sampler_constructor, coordinate_expr, index_expr
|
||||
)
|
||||
}
|
||||
}
|
||||
ImageClass::Storage(_, _) => {
|
||||
format!("imageLoad({},{})", image_expr, coordinate_expr)
|
||||
}
|
||||
ImageClass::Depth => todo!(),
|
||||
};
|
||||
|
||||
let width = 4;
|
||||
@ -909,7 +968,25 @@ fn write_expression<'a, 'b>(
|
||||
"({} {})",
|
||||
match op {
|
||||
UnaryOperator::Negate => "-",
|
||||
UnaryOperator::Not => "~",
|
||||
UnaryOperator::Not => match ty.as_ref() {
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
..
|
||||
} => "~",
|
||||
TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
..
|
||||
} => "!",
|
||||
_ =>
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot apply not to type {:?}",
|
||||
ty
|
||||
))),
|
||||
},
|
||||
},
|
||||
expr
|
||||
)),
|
||||
@ -922,7 +999,7 @@ fn write_expression<'a, 'b>(
|
||||
let (right_expr, right_ty) =
|
||||
write_expression(&builder.expressions[right], module, builder)?;
|
||||
|
||||
let op = match op {
|
||||
let op_str = match op {
|
||||
BinaryOperator::Add => "+",
|
||||
BinaryOperator::Subtract => "-",
|
||||
BinaryOperator::Multiply => "*",
|
||||
@ -944,26 +1021,51 @@ fn write_expression<'a, 'b>(
|
||||
BinaryOperator::ShiftRightArithmetic => ">>",
|
||||
};
|
||||
|
||||
let ty = match (left_ty.as_ref(), right_ty.as_ref()) {
|
||||
(TypeInner::Scalar { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Scalar { .. }, TypeInner::Vector { .. }) => right_ty,
|
||||
(TypeInner::Scalar { .. }, TypeInner::Matrix { .. }) => right_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Vector { .. }) => left_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Matrix { .. }) => left_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Vector { .. }) => right_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Matrix { .. }) => left_ty,
|
||||
_ => {
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot apply {} to {} and {}",
|
||||
op, left_expr, right_expr
|
||||
)))
|
||||
let ty = match op {
|
||||
BinaryOperator::Add
|
||||
| BinaryOperator::Subtract
|
||||
| BinaryOperator::Multiply
|
||||
| BinaryOperator::Divide
|
||||
| BinaryOperator::Modulo
|
||||
| BinaryOperator::And
|
||||
| BinaryOperator::ExclusiveOr
|
||||
| BinaryOperator::InclusiveOr
|
||||
| BinaryOperator::LogicalAnd
|
||||
| BinaryOperator::LogicalOr
|
||||
| BinaryOperator::ShiftLeftLogical
|
||||
| BinaryOperator::ShiftRightLogical
|
||||
| BinaryOperator::ShiftRightArithmetic => {
|
||||
match (left_ty.as_ref(), right_ty.as_ref()) {
|
||||
(TypeInner::Scalar { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Scalar { .. }, TypeInner::Vector { .. }) => right_ty,
|
||||
(TypeInner::Scalar { .. }, TypeInner::Matrix { .. }) => right_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Vector { .. }) => left_ty,
|
||||
(TypeInner::Vector { .. }, TypeInner::Matrix { .. }) => left_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Scalar { .. }) => left_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Vector { .. }) => right_ty,
|
||||
(TypeInner::Matrix { .. }, TypeInner::Matrix { .. }) => left_ty,
|
||||
_ => {
|
||||
return Err(Error::Custom(format!(
|
||||
"Cannot apply '{}' to {} and {}",
|
||||
op_str, left_expr, right_expr
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
BinaryOperator::Equal
|
||||
| BinaryOperator::NotEqual
|
||||
| BinaryOperator::Less
|
||||
| BinaryOperator::LessEqual
|
||||
| BinaryOperator::Greater
|
||||
| BinaryOperator::GreaterEqual => Cow::Owned(TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
width: 1,
|
||||
}),
|
||||
};
|
||||
|
||||
(
|
||||
Cow::Owned(format!("({} {} {})", left_expr, op, right_expr)),
|
||||
Cow::Owned(format!("({} {} {})", left_expr, op_str, right_expr)),
|
||||
ty,
|
||||
)
|
||||
}
|
||||
@ -1284,7 +1386,7 @@ fn write_type<'a>(
|
||||
}
|
||||
|
||||
Cow::Owned(format!(
|
||||
"{}texture{}{}",
|
||||
"{}{}{}{}",
|
||||
match kind {
|
||||
ScalarKind::Sint => "i",
|
||||
ScalarKind::Uint => "u",
|
||||
@ -1294,6 +1396,10 @@ fn write_type<'a>(
|
||||
"Cannot build image of booleans",
|
||||
))),
|
||||
},
|
||||
match class {
|
||||
ImageClass::Storage(_, _) => "image",
|
||||
_ => "texture",
|
||||
},
|
||||
ImageDimension(dim),
|
||||
write_image_flags(arrayed, class, features)?
|
||||
))
|
||||
@ -1460,9 +1566,9 @@ fn write_struct(
|
||||
|
||||
fn is_valid_ident(ident: &str) -> bool {
|
||||
ident.starts_with(|c: char| c.is_ascii_alphabetic() || c == '_')
|
||||
|| ident.contains(|c: char| c.is_ascii_alphanumeric() || c == '_')
|
||||
|| !ident.starts_with("gl_")
|
||||
|| ident != "main"
|
||||
&& ident.contains(|c: char| c.is_ascii_alphanumeric() || c == '_')
|
||||
&& !ident.starts_with("gl_")
|
||||
&& ident != "main"
|
||||
}
|
||||
|
||||
fn builtin_to_glsl(builtin: BuiltIn) -> &'static str {
|
||||
@ -1484,3 +1590,9 @@ fn builtin_to_glsl(builtin: BuiltIn) -> &'static str {
|
||||
BuiltIn::WorkGroupId => "gl_WorkGroupID",
|
||||
}
|
||||
}
|
||||
|
||||
fn write_format_glsl(format: StorageFormat) -> &'static str {
|
||||
match format {
|
||||
StorageFormat::Rgba32f => "rgba32f",
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user