mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-25 08:13:27 +00:00
[naga] Introduce Scalar
type to IR.
Introduce a new struct type, `Scalar`, combining a `ScalarKind` and a `Bytes` width, and use this whenever such pairs of values are passed around. In particular, use `Scalar` in `TypeInner` variants `Scalar`, `Vector`, `Atomic`, and `ValuePointer`. Introduce associated `Scalar` constants `I32`, `U32`, `F32`, `BOOL` and `F64`, for common cases. Introduce a helper function `Scalar::float` for constructing `Float` scalars of a given width, for dealing with `TypeInner::Matrix`, which only supplies the scalar width of its elements, not a kind. Introduce helper functions on `Literal` and `TypeInner`, to produce the `Scalar` describing elements' values. Use `Scalar` in `wgpu_core::validation::NumericType` as well.
This commit is contained in:
parent
049cb75976
commit
9f91c95c24
@ -49,6 +49,10 @@ For naga changelogs at or before v0.14.0. See [naga's changelog](naga/CHANGELOG.
|
||||
- Log vulkan validation layer messages during instance creation and destruction: By @exrook in [#4586](https://github.com/gfx-rs/wgpu/pull/4586)
|
||||
- `TextureFormat::block_size` is deprecated, use `TextureFormat::block_copy_size` instead: By @wumpf in [#4647](https://github.com/gfx-rs/wgpu/pull/4647)
|
||||
|
||||
#### Naga
|
||||
|
||||
- Introduce a new `Scalar` struct type for use in Naga's IR, and update all frontend, middle, and backend code appropriately. By @jimblandy in [#4673](https://github.com/gfx-rs/wgpu/pull/4673).
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
#### WGL
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::{BackendResult, Error, Version, Writer};
|
||||
use crate::{
|
||||
AddressSpace, Binding, Bytes, Expression, Handle, ImageClass, ImageDimension, Interpolation,
|
||||
Sampling, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
|
||||
AddressSpace, Binding, Expression, Handle, ImageClass, ImageDimension, Interpolation, Sampling,
|
||||
Scalar, ScalarKind, ShaderStage, StorageFormat, Type, TypeInner,
|
||||
};
|
||||
use std::fmt::Write;
|
||||
|
||||
@ -275,10 +275,10 @@ impl<'a, W> Writer<'a, W> {
|
||||
|
||||
for (ty_handle, ty) in self.module.types.iter() {
|
||||
match ty.inner {
|
||||
TypeInner::Scalar { kind, width } => self.scalar_required_features(kind, width),
|
||||
TypeInner::Vector { kind, width, .. } => self.scalar_required_features(kind, width),
|
||||
TypeInner::Scalar(scalar) => self.scalar_required_features(scalar),
|
||||
TypeInner::Vector { scalar, .. } => self.scalar_required_features(scalar),
|
||||
TypeInner::Matrix { width, .. } => {
|
||||
self.scalar_required_features(ScalarKind::Float, width)
|
||||
self.scalar_required_features(Scalar::float(width))
|
||||
}
|
||||
TypeInner::Array { base, size, .. } => {
|
||||
if let TypeInner::Array { .. } = self.module.types[base].inner {
|
||||
@ -463,8 +463,8 @@ impl<'a, W> Writer<'a, W> {
|
||||
}
|
||||
|
||||
/// Helper method that checks the [`Features`] needed by a scalar
|
||||
fn scalar_required_features(&mut self, kind: ScalarKind, width: Bytes) {
|
||||
if kind == ScalarKind::Float && width == 8 {
|
||||
fn scalar_required_features(&mut self, scalar: Scalar) {
|
||||
if scalar.kind == ScalarKind::Float && scalar.width == 8 {
|
||||
self.features.request(Features::DOUBLE_TYPE);
|
||||
}
|
||||
}
|
||||
|
@ -471,8 +471,8 @@ pub enum Error {
|
||||
#[error("A call was made to an unsupported external: {0}")]
|
||||
UnsupportedExternal(String),
|
||||
/// A scalar with an unsupported width was requested.
|
||||
#[error("A scalar with an unsupported width was requested: {0:?} {1:?}")]
|
||||
UnsupportedScalar(crate::ScalarKind, crate::Bytes),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?}")]
|
||||
UnsupportedScalar(crate::Scalar),
|
||||
/// A image was used with multiple samplers, which isn't supported.
|
||||
#[error("A image was used with multiple samplers")]
|
||||
ImageMultipleSamplers,
|
||||
@ -963,27 +963,20 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
fn write_value_type(&mut self, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
// Scalars are simple we just get the full name from `glsl_scalar`
|
||||
TypeInner::Scalar { kind, width }
|
||||
| TypeInner::Atomic { kind, width }
|
||||
TypeInner::Scalar(scalar)
|
||||
| TypeInner::Atomic(scalar)
|
||||
| TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => write!(self.out, "{}", glsl_scalar(kind, width)?.full)?,
|
||||
} => write!(self.out, "{}", glsl_scalar(scalar)?.full)?,
|
||||
// Vectors are just `gvecN` where `g` is the scalar prefix and `N` is the vector size
|
||||
TypeInner::Vector { size, kind, width }
|
||||
TypeInner::Vector { size, scalar }
|
||||
| TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => write!(
|
||||
self.out,
|
||||
"{}vec{}",
|
||||
glsl_scalar(kind, width)?.prefix,
|
||||
size as u8
|
||||
)?,
|
||||
} => write!(self.out, "{}vec{}", glsl_scalar(scalar)?.prefix, size as u8)?,
|
||||
// Matrices are written with `gmatMxN` where `g` is the scalar prefix (only floats and
|
||||
// doubles are allowed), `M` is the columns count and `N` is the rows count
|
||||
//
|
||||
@ -996,7 +989,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
} => write!(
|
||||
self.out,
|
||||
"{}mat{}x{}",
|
||||
glsl_scalar(crate::ScalarKind::Float, width)?.prefix,
|
||||
glsl_scalar(crate::Scalar::float(width))?.prefix,
|
||||
columns as u8,
|
||||
rows as u8
|
||||
)?,
|
||||
@ -1083,7 +1076,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
self.out,
|
||||
"{}{}{}{}{}{}{}",
|
||||
precision,
|
||||
glsl_scalar(kind, 4)?.prefix,
|
||||
glsl_scalar(crate::Scalar { kind, width: 4 })?.prefix,
|
||||
base,
|
||||
glsl_dimension(dim),
|
||||
ms,
|
||||
@ -1278,7 +1271,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
crate::MathFunction::Dot => {
|
||||
// if the expression is a Dot product with integer arguments,
|
||||
// then the args needs baking as well
|
||||
if let TypeInner::Scalar { kind, .. } = *inner {
|
||||
if let TypeInner::Scalar(crate::Scalar { kind, .. }) = *inner {
|
||||
match kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
self.need_bake_expressions.insert(arg);
|
||||
@ -2802,10 +2795,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
if let Some(expr) = level {
|
||||
let cast_to_int = matches!(
|
||||
*ctx.resolve_type(expr, &self.module.types),
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
write!(self.out, ", ")?;
|
||||
@ -2906,19 +2899,19 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
let right_inner = ctx.resolve_type(right, &self.module.types);
|
||||
|
||||
let function = match (left_inner, right_inner) {
|
||||
(&Ti::Vector { kind, .. }, &Ti::Vector { .. }) => match op {
|
||||
(&Ti::Vector { scalar, .. }, &Ti::Vector { .. }) => match op {
|
||||
Bo::Less
|
||||
| Bo::LessEqual
|
||||
| Bo::Greater
|
||||
| Bo::GreaterEqual
|
||||
| Bo::Equal
|
||||
| Bo::NotEqual => BinaryOperation::VectorCompare,
|
||||
Bo::Modulo if kind == Sk::Float => BinaryOperation::Modulo,
|
||||
Bo::And if kind == Sk::Bool => {
|
||||
Bo::Modulo if scalar.kind == Sk::Float => BinaryOperation::Modulo,
|
||||
Bo::And if scalar.kind == Sk::Bool => {
|
||||
op = crate::BinaryOperator::LogicalAnd;
|
||||
BinaryOperation::VectorComponentWise
|
||||
}
|
||||
Bo::InclusiveOr if kind == Sk::Bool => {
|
||||
Bo::InclusiveOr if scalar.kind == Sk::Bool => {
|
||||
op = crate::BinaryOperator::LogicalOr;
|
||||
BinaryOperation::VectorComponentWise
|
||||
}
|
||||
@ -3171,7 +3164,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// geometry
|
||||
Mf::Dot => match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => "dot",
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
@ -3226,9 +3223,9 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// bits
|
||||
Mf::CountTrailingZeros => {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar, .. } => {
|
||||
let s = back::vector_size_str(size);
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(uvec{s}(findLSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ")), uvec{s}(32u))")?;
|
||||
@ -3238,8 +3235,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ")), uvec{s}(32u)))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(uint(findLSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ")), 32u)")?;
|
||||
@ -3256,10 +3253,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
Mf::CountLeadingZeros => {
|
||||
if self.options.version.supports_integer_functions() {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let s = back::vector_size_str(size);
|
||||
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uvec{s}(ivec{s}(31) - findMSB(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -3271,8 +3268,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ", ivec{s}(0)))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uint(31 - findMSB(")?;
|
||||
} else {
|
||||
write!(self.out, "(")?;
|
||||
@ -3287,10 +3284,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
};
|
||||
} else {
|
||||
match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let s = back::vector_size_str(size);
|
||||
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uvec{s}(")?;
|
||||
write!(self.out, "vec{s}(31.0) - floor(log2(vec{s}(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
@ -3305,8 +3302,8 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
write!(self.out, ", ivec{s}(0u))))")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Uint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "uint(31.0 - floor(log2(float(")?;
|
||||
self.write_expr(arg, ctx)?;
|
||||
write!(self.out, ") + 0.5)))")?;
|
||||
@ -3360,14 +3357,17 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Check if the argument is an unsigned integer and return the vector size
|
||||
// in case it's a vector
|
||||
let maybe_uint_size = match *ctx.resolve_type(arg, &self.module.types) {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(None),
|
||||
}) => Some(None),
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
size,
|
||||
..
|
||||
} => Some(Some(size)),
|
||||
_ => None,
|
||||
};
|
||||
@ -3450,7 +3450,10 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
match convert {
|
||||
Some(width) => {
|
||||
// this is similar to `write_type`, but with the target kind
|
||||
let scalar = glsl_scalar(target_kind, width)?;
|
||||
let scalar = glsl_scalar(crate::Scalar {
|
||||
kind: target_kind,
|
||||
width,
|
||||
})?;
|
||||
match *inner {
|
||||
TypeInner::Matrix { columns, rows, .. } => write!(
|
||||
self.out,
|
||||
@ -3471,10 +3474,12 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let target_vector_type = match *inner {
|
||||
TypeInner::Vector { size, width, .. } => Some(TypeInner::Vector {
|
||||
TypeInner::Vector { size, scalar } => Some(TypeInner::Vector {
|
||||
size,
|
||||
width,
|
||||
kind: target_kind,
|
||||
scalar: crate::Scalar {
|
||||
kind: target_kind,
|
||||
width: scalar.width,
|
||||
},
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
@ -3613,14 +3618,17 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// Otherwise write just the expression (and the 1D hack if needed)
|
||||
None => {
|
||||
let uvec_size = match *ctx.resolve_type(coordinate, &self.module.types) {
|
||||
TypeInner::Scalar {
|
||||
TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(None),
|
||||
}) => Some(None),
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(Some(size as u32)),
|
||||
_ => None,
|
||||
};
|
||||
@ -3953,7 +3961,11 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
// End the first branch
|
||||
write!(self.out, " : ")?;
|
||||
// Write the 0 value
|
||||
write!(self.out, "{}vec4(", glsl_scalar(kind, 4)?.prefix,)?;
|
||||
write!(
|
||||
self.out,
|
||||
"{}vec4(",
|
||||
glsl_scalar(crate::Scalar { kind, width: 4 })?.prefix,
|
||||
)?;
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
// Close the zero value constructor
|
||||
write!(self.out, ")")?;
|
||||
@ -4006,13 +4018,13 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
fn write_zero_init_value(&mut self, ty: Handle<crate::Type>) -> BackendResult {
|
||||
let inner = &self.module.types[ty].inner;
|
||||
match *inner {
|
||||
TypeInner::Scalar { kind, .. } | TypeInner::Atomic { kind, .. } => {
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
TypeInner::Scalar(scalar) | TypeInner::Atomic(scalar) => {
|
||||
self.write_zero_init_scalar(scalar.kind)?;
|
||||
}
|
||||
TypeInner::Vector { kind, .. } => {
|
||||
TypeInner::Vector { scalar, .. } => {
|
||||
self.write_value_type(inner)?;
|
||||
write!(self.out, "(")?;
|
||||
self.write_zero_init_scalar(kind)?;
|
||||
self.write_zero_init_scalar(scalar.kind)?;
|
||||
write!(self.out, ")")?;
|
||||
}
|
||||
TypeInner::Matrix { .. } => {
|
||||
@ -4265,13 +4277,10 @@ struct ScalarString<'a> {
|
||||
///
|
||||
/// # Errors
|
||||
/// If a [`Float`](crate::ScalarKind::Float) with an width that isn't 4 or 8
|
||||
const fn glsl_scalar(
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Result<ScalarString<'static>, Error> {
|
||||
const fn glsl_scalar(scalar: crate::Scalar) -> Result<ScalarString<'static>, Error> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
Ok(match kind {
|
||||
Ok(match scalar.kind {
|
||||
Sk::Sint => ScalarString {
|
||||
prefix: "i",
|
||||
full: "int",
|
||||
@ -4280,7 +4289,7 @@ const fn glsl_scalar(
|
||||
prefix: "u",
|
||||
full: "uint",
|
||||
},
|
||||
Sk::Float => match width {
|
||||
Sk::Float => match scalar.width {
|
||||
4 => ScalarString {
|
||||
prefix: "",
|
||||
full: "float",
|
||||
@ -4289,7 +4298,7 @@ const fn glsl_scalar(
|
||||
prefix: "d",
|
||||
full: "double",
|
||||
},
|
||||
_ => return Err(Error::UnsupportedScalar(kind, width)),
|
||||
_ => return Err(Error::UnsupportedScalar(scalar)),
|
||||
},
|
||||
Sk::Bool => ScalarString {
|
||||
prefix: "b",
|
||||
|
@ -13,21 +13,23 @@ impl crate::ScalarKind {
|
||||
Self::Bool => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Scalar {
|
||||
/// Helper function that returns scalar related strings
|
||||
///
|
||||
/// <https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-scalar>
|
||||
pub(super) const fn to_hlsl_str(self, width: crate::Bytes) -> Result<&'static str, Error> {
|
||||
match self {
|
||||
Self::Sint => Ok("int"),
|
||||
Self::Uint => Ok("uint"),
|
||||
Self::Float => match width {
|
||||
pub(super) const fn to_hlsl_str(self) -> Result<&'static str, Error> {
|
||||
match self.kind {
|
||||
crate::ScalarKind::Sint => Ok("int"),
|
||||
crate::ScalarKind::Uint => Ok("uint"),
|
||||
crate::ScalarKind::Float => match self.width {
|
||||
2 => Ok("half"),
|
||||
4 => Ok("float"),
|
||||
8 => Ok("double"),
|
||||
_ => Err(Error::UnsupportedScalar(self, width)),
|
||||
_ => Err(Error::UnsupportedScalar(self)),
|
||||
},
|
||||
Self::Bool => Ok("bool"),
|
||||
crate::ScalarKind::Bool => Ok("bool"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -71,10 +73,10 @@ impl crate::TypeInner {
|
||||
names: &'a crate::FastHashMap<crate::proc::NameKey, String>,
|
||||
) -> Result<Cow<'a, str>, Error> {
|
||||
Ok(match gctx.types[base].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => Cow::Borrowed(kind.to_hlsl_str(width)?),
|
||||
crate::TypeInner::Vector { size, kind, width } => Cow::Owned(format!(
|
||||
crate::TypeInner::Scalar(scalar) => Cow::Borrowed(scalar.to_hlsl_str()?),
|
||||
crate::TypeInner::Vector { size, scalar } => Cow::Owned(format!(
|
||||
"{}{}",
|
||||
kind.to_hlsl_str(width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
crate::back::vector_size_str(size)
|
||||
)),
|
||||
crate::TypeInner::Matrix {
|
||||
@ -83,7 +85,7 @@ impl crate::TypeInner {
|
||||
width,
|
||||
} => Cow::Owned(format!(
|
||||
"{}{}x{}",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
crate::back::vector_size_str(columns),
|
||||
crate::back::vector_size_str(rows),
|
||||
)),
|
||||
|
@ -133,7 +133,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
}
|
||||
crate::ImageClass::Sampled { kind, multi } => {
|
||||
let multi_str = if multi { "MS" } else { "" };
|
||||
let scalar_kind_str = kind.to_hlsl_str(4)?;
|
||||
let scalar_kind_str = crate::Scalar { kind, width: 4 }.to_hlsl_str()?;
|
||||
write!(self.out, "{multi_str}<{scalar_kind_str}4>")?
|
||||
}
|
||||
crate::ImageClass::Storage { format, .. } => {
|
||||
@ -658,8 +658,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
let vec_ty = match module.types[member.ty].inner {
|
||||
crate::TypeInner::Matrix { rows, width, .. } => crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -737,10 +736,9 @@ impl<'a, W: Write> super::Writer<'a, W> {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
let scalar_ty = match module.types[member.ty].inner {
|
||||
crate::TypeInner::Matrix { width, .. } => crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
crate::TypeInner::Matrix { width, .. } => {
|
||||
crate::TypeInner::Scalar(crate::Scalar::float(width))
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
self.write_value_type(module, &scalar_ty)?;
|
||||
|
@ -241,8 +241,8 @@ pub struct ReflectionInfo {
|
||||
pub enum Error {
|
||||
#[error(transparent)]
|
||||
IoError(#[from] FmtError),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?} {1:?}")]
|
||||
UnsupportedScalar(crate::ScalarKind, crate::Bytes),
|
||||
#[error("A scalar with an unsupported width was requested: {0:?}")]
|
||||
UnsupportedScalar(crate::Scalar),
|
||||
#[error("{0}")]
|
||||
Unimplemented(String), // TODO: Error used only during development
|
||||
#[error("{0}")]
|
||||
|
@ -157,25 +157,21 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
func_ctx: &FunctionCtx,
|
||||
) -> BackendResult {
|
||||
match *result_ty.inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { kind, width: _ } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
let cast = kind.to_hlsl_cast();
|
||||
let cast = scalar.kind.to_hlsl_cast();
|
||||
write!(self.out, "{cast}({var_name}.Load(")?;
|
||||
self.write_storage_address(module, &chain, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
self.temp_access_chain = chain;
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: _,
|
||||
} => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
let cast = kind.to_hlsl_cast();
|
||||
let cast = scalar.kind.to_hlsl_cast();
|
||||
write!(self.out, "{}({}.Load{}(", cast, var_name, size as u8)?;
|
||||
self.write_storage_address(module, &chain, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -189,7 +185,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}(",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
columns as u8,
|
||||
rows as u8,
|
||||
)?;
|
||||
@ -199,8 +195,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
let iter = (0..columns as u32).map(|i| {
|
||||
let ty_inner = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
(TypeResolution::Value(ty_inner), i * row_stride)
|
||||
});
|
||||
@ -296,7 +291,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
}
|
||||
};
|
||||
match *ty_resolution.inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { .. } => {
|
||||
crate::TypeInner::Scalar(_) => {
|
||||
// working around the borrow checker in `self.write_expr`
|
||||
let chain = mem::take(&mut self.temp_access_chain);
|
||||
let var_name = &self.names[&NameKey::GlobalVariable(var_handle)];
|
||||
@ -330,7 +325,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
self.out,
|
||||
"{}{}{}x{} {}{} = ",
|
||||
level.next(),
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
columns as u8,
|
||||
rows as u8,
|
||||
STORE_TEMP_NAME,
|
||||
@ -348,8 +343,7 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
.push(SubAccess::Offset(i * row_stride));
|
||||
let ty_inner = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
let sv = StoreValue::TempIndex {
|
||||
depth,
|
||||
@ -470,8 +464,8 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
|
||||
crate::TypeInner::Struct { ref members, .. } => Parent::Struct(members),
|
||||
crate::TypeInner::Array { stride, .. } => Parent::Array { stride },
|
||||
crate::TypeInner::Vector { width, .. } => Parent::Array {
|
||||
stride: width as u32,
|
||||
crate::TypeInner::Vector { scalar, .. } => Parent::Array {
|
||||
stride: scalar.width as u32,
|
||||
},
|
||||
crate::TypeInner::Matrix { rows, width, .. } => Parent::Array {
|
||||
// The stride between matrices is the count of rows as this is how
|
||||
@ -480,8 +474,8 @@ impl<W: fmt::Write> super::Writer<'_, W> {
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
crate::TypeInner::ValuePointer { width, .. } => Parent::Array {
|
||||
stride: width as u32,
|
||||
crate::TypeInner::ValuePointer { scalar, .. } => Parent::Array {
|
||||
stride: scalar.width as u32,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -912,8 +912,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
} if member.binding.is_none() && rows == crate::VectorSize::Bi => {
|
||||
let vec_ty = crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
let field_name_key = NameKey::StructMember(handle, index as u32);
|
||||
|
||||
@ -1024,14 +1023,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
/// Adds no trailing or leading whitespace
|
||||
pub(super) fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
TypeInner::Scalar { kind, width } | TypeInner::Atomic { kind, width } => {
|
||||
write!(self.out, "{}", kind.to_hlsl_str(width)?)?;
|
||||
TypeInner::Scalar(scalar) | TypeInner::Atomic(scalar) => {
|
||||
write!(self.out, "{}", scalar.to_hlsl_str()?)?;
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}",
|
||||
kind.to_hlsl_str(width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(size)
|
||||
)?;
|
||||
}
|
||||
@ -1047,7 +1046,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}",
|
||||
crate::ScalarKind::Float.to_hlsl_str(width)?,
|
||||
crate::Scalar::float(width).to_hlsl_str()?,
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows),
|
||||
)?;
|
||||
@ -2484,7 +2483,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")")?;
|
||||
|
||||
// return x component if return type is scalar
|
||||
if let TypeInner::Scalar { .. } = *func_ctx.resolve_type(expr, &module.types) {
|
||||
if let TypeInner::Scalar(_) = *func_ctx.resolve_type(expr, &module.types) {
|
||||
write!(self.out, ".x")?;
|
||||
}
|
||||
}
|
||||
@ -2567,23 +2566,27 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
let inner = func_ctx.resolve_type(expr, &module.types);
|
||||
match convert {
|
||||
Some(dst_width) => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: dst_width,
|
||||
};
|
||||
match *inner {
|
||||
TypeInner::Vector { size, .. } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}(",
|
||||
kind.to_hlsl_str(dst_width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(size)
|
||||
)?;
|
||||
}
|
||||
TypeInner::Scalar { .. } => {
|
||||
write!(self.out, "{}(", kind.to_hlsl_str(dst_width)?,)?;
|
||||
TypeInner::Scalar(_) => {
|
||||
write!(self.out, "{}(", scalar.to_hlsl_str()?,)?;
|
||||
}
|
||||
TypeInner::Matrix { columns, rows, .. } => {
|
||||
write!(
|
||||
self.out,
|
||||
"{}{}x{}(",
|
||||
kind.to_hlsl_str(dst_width)?,
|
||||
scalar.to_hlsl_str()?,
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows)
|
||||
)?;
|
||||
@ -2964,14 +2967,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
}
|
||||
Function::CountTrailingZeros => {
|
||||
match *func_ctx.resolve_type(arg, &module.types) {
|
||||
TypeInner::Vector { size, kind, .. } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let s = match size {
|
||||
crate::VectorSize::Bi => ".xx",
|
||||
crate::VectorSize::Tri => ".xxx",
|
||||
crate::VectorSize::Quad => ".xxxx",
|
||||
};
|
||||
|
||||
if let ScalarKind::Uint = kind {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min((32u){s}, firstbitlow(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -2981,8 +2984,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")))")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, .. } => {
|
||||
if let ScalarKind::Uint = kind {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "min(32u, firstbitlow(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -2999,14 +3002,14 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
}
|
||||
Function::CountLeadingZeros => {
|
||||
match *func_ctx.resolve_type(arg, &module.types) {
|
||||
TypeInner::Vector { size, kind, .. } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let s = match size {
|
||||
crate::VectorSize::Bi => ".xx",
|
||||
crate::VectorSize::Tri => ".xxx",
|
||||
crate::VectorSize::Quad => ".xxxx",
|
||||
};
|
||||
|
||||
if let ScalarKind::Uint = kind {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "((31u){s} - firstbithigh(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
@ -3021,8 +3024,8 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
|
||||
write!(self.out, ")))")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, .. } => {
|
||||
if let ScalarKind::Uint = kind {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
if let ScalarKind::Uint = scalar.kind {
|
||||
write!(self.out, "(31u - firstbithigh(")?;
|
||||
self.write_expr(module, arg, func_ctx)?;
|
||||
write!(self.out, "))")?;
|
||||
|
@ -45,28 +45,28 @@ pub(crate) const FREXP_FUNCTION: &str = "naga_frexp";
|
||||
/// - A two element slice `[ROWS COLUMNS]` produces a matrix of the given size.
|
||||
fn put_numeric_type(
|
||||
out: &mut impl Write,
|
||||
kind: crate::ScalarKind,
|
||||
scalar: crate::Scalar,
|
||||
sizes: &[crate::VectorSize],
|
||||
) -> Result<(), FmtError> {
|
||||
match (kind, sizes) {
|
||||
(kind, &[]) => {
|
||||
write!(out, "{}", kind.to_msl_name())
|
||||
match (scalar, sizes) {
|
||||
(scalar, &[]) => {
|
||||
write!(out, "{}", scalar.to_msl_name())
|
||||
}
|
||||
(kind, &[rows]) => {
|
||||
(scalar, &[rows]) => {
|
||||
write!(
|
||||
out,
|
||||
"{}::{}{}",
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
back::vector_size_str(rows)
|
||||
)
|
||||
}
|
||||
(kind, &[rows, columns]) => {
|
||||
(scalar, &[rows, columns]) => {
|
||||
write!(
|
||||
out,
|
||||
"{}::{}{}x{}",
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
back::vector_size_str(columns),
|
||||
back::vector_size_str(rows)
|
||||
)
|
||||
@ -96,13 +96,13 @@ impl<'a> Display for TypeContext<'a> {
|
||||
}
|
||||
|
||||
match ty.inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => put_numeric_type(out, kind, &[]),
|
||||
crate::TypeInner::Atomic { kind, .. } => {
|
||||
write!(out, "{}::atomic_{}", NAMESPACE, kind.to_msl_name())
|
||||
crate::TypeInner::Scalar(scalar) => put_numeric_type(out, scalar, &[]),
|
||||
crate::TypeInner::Atomic(scalar) => {
|
||||
write!(out, "{}::atomic_{}", NAMESPACE, scalar.to_msl_name())
|
||||
}
|
||||
crate::TypeInner::Vector { size, kind, .. } => put_numeric_type(out, kind, &[size]),
|
||||
crate::TypeInner::Vector { size, scalar } => put_numeric_type(out, scalar, &[size]),
|
||||
crate::TypeInner::Matrix { columns, rows, .. } => {
|
||||
put_numeric_type(out, crate::ScalarKind::Float, &[rows, columns])
|
||||
put_numeric_type(out, crate::Scalar::F32, &[rows, columns])
|
||||
}
|
||||
crate::TypeInner::Pointer { base, space } => {
|
||||
let sub = Self {
|
||||
@ -118,8 +118,7 @@ impl<'a> Display for TypeContext<'a> {
|
||||
}
|
||||
crate::TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width: _,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
match space.to_msl_name() {
|
||||
@ -127,8 +126,8 @@ impl<'a> Display for TypeContext<'a> {
|
||||
None => return Ok(()),
|
||||
};
|
||||
match size {
|
||||
Some(rows) => put_numeric_type(out, kind, &[rows])?,
|
||||
None => put_numeric_type(out, kind, &[])?,
|
||||
Some(rows) => put_numeric_type(out, scalar, &[rows])?,
|
||||
None => put_numeric_type(out, scalar, &[])?,
|
||||
};
|
||||
|
||||
write!(out, "&")
|
||||
@ -194,7 +193,7 @@ impl<'a> Display for TypeContext<'a> {
|
||||
("texture", "", format.into(), access)
|
||||
}
|
||||
};
|
||||
let base_name = kind.to_msl_name();
|
||||
let base_name = crate::Scalar { kind, width: 4 }.to_msl_name();
|
||||
let array_str = if arrayed { "_array" } else { "" };
|
||||
write!(
|
||||
out,
|
||||
@ -319,13 +318,26 @@ pub struct Writer<W> {
|
||||
struct_member_pads: FastHashSet<(Handle<crate::Type>, u32)>,
|
||||
}
|
||||
|
||||
impl crate::ScalarKind {
|
||||
impl crate::Scalar {
|
||||
const fn to_msl_name(self) -> &'static str {
|
||||
use crate::ScalarKind as Sk;
|
||||
match self {
|
||||
Self::Float => "float",
|
||||
Self::Sint => "int",
|
||||
Self::Uint => "uint",
|
||||
Self::Bool => "bool",
|
||||
Self {
|
||||
kind: Sk::Float,
|
||||
width: _,
|
||||
} => "float",
|
||||
Self {
|
||||
kind: Sk::Sint,
|
||||
width: _,
|
||||
} => "int",
|
||||
Self {
|
||||
kind: Sk::Uint,
|
||||
width: _,
|
||||
} => "uint",
|
||||
Self {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
} => "bool",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -343,7 +355,7 @@ fn should_pack_struct_member(
|
||||
span: u32,
|
||||
index: usize,
|
||||
module: &crate::Module,
|
||||
) -> Option<crate::ScalarKind> {
|
||||
) -> Option<crate::Scalar> {
|
||||
let member = &members[index];
|
||||
//Note: this is imperfect - the same structure can be used for host-shared
|
||||
// things, where packed float would matter.
|
||||
@ -362,9 +374,8 @@ fn should_pack_struct_member(
|
||||
match *ty_inner {
|
||||
crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
width: 4,
|
||||
kind,
|
||||
} if member.offset & 0xF != 0 || is_tight => Some(kind),
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
} if member.offset & 0xF != 0 || is_tight => Some(scalar),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@ -442,10 +453,10 @@ impl crate::Type {
|
||||
|
||||
match self.inner {
|
||||
// value types are concise enough, we only alias them if they are named
|
||||
Ti::Scalar { .. }
|
||||
Ti::Scalar(_)
|
||||
| Ti::Vector { .. }
|
||||
| Ti::Matrix { .. }
|
||||
| Ti::Atomic { .. }
|
||||
| Ti::Atomic(_)
|
||||
| Ti::Pointer { .. }
|
||||
| Ti::ValuePointer { .. } => self.name.is_some(),
|
||||
// composite types are better to be aliased, regardless of the name
|
||||
@ -549,10 +560,7 @@ impl<'a> ExpressionContext<'a> {
|
||||
index::access_needs_check(base, index, self.module, self.function, self.info)
|
||||
}
|
||||
|
||||
fn get_packed_vec_kind(
|
||||
&self,
|
||||
expr_handle: Handle<crate::Expression>,
|
||||
) -> Option<crate::ScalarKind> {
|
||||
fn get_packed_vec_kind(&self, expr_handle: Handle<crate::Expression>) -> Option<crate::Scalar> {
|
||||
match self.function.expressions[expr_handle] {
|
||||
crate::Expression::AccessIndex { base, index } => {
|
||||
let ty = match *self.resolve_type(base) {
|
||||
@ -673,7 +681,8 @@ impl<W: Write> Writer<W> {
|
||||
crate::TypeInner::Image { dim, .. } => dim,
|
||||
ref other => unreachable!("Unexpected type {:?}", other),
|
||||
};
|
||||
let coordinate_type = kind.to_msl_name();
|
||||
let scalar = crate::Scalar { kind, width: 4 };
|
||||
let coordinate_type = scalar.to_msl_name();
|
||||
match dim {
|
||||
crate::ImageDimension::D1 => {
|
||||
// Since 1D textures never have mipmaps, MSL requires that the
|
||||
@ -721,11 +730,11 @@ impl<W: Write> Writer<W> {
|
||||
) -> BackendResult {
|
||||
// coordinates in IR are int, but Metal expects uint
|
||||
match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Scalar { .. } => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Uint, &[])?
|
||||
crate::TypeInner::Scalar(_) => {
|
||||
put_numeric_type(&mut self.out, crate::Scalar::U32, &[])?
|
||||
}
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Uint, &[size])?
|
||||
put_numeric_type(&mut self.out, crate::Scalar::U32, &[size])?
|
||||
}
|
||||
_ => return Err(Error::Validation),
|
||||
};
|
||||
@ -1299,7 +1308,7 @@ impl<W: Write> Writer<W> {
|
||||
};
|
||||
write!(self.out, "{ty_name}")?;
|
||||
match module.types[ty].inner {
|
||||
crate::TypeInner::Scalar { .. }
|
||||
crate::TypeInner::Scalar(_)
|
||||
| crate::TypeInner::Vector { .. }
|
||||
| crate::TypeInner::Matrix { .. } => {
|
||||
self.put_call_parameters_impl(
|
||||
@ -1326,11 +1335,11 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
}
|
||||
crate::Expression::Splat { size, value } => {
|
||||
let scalar_kind = match *get_expr_ty(ctx, value).inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar { kind, .. } => kind,
|
||||
let scalar = match *get_expr_ty(ctx, value).inner_with(&module.types) {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::Validation),
|
||||
};
|
||||
put_numeric_type(&mut self.out, scalar_kind, &[size])?;
|
||||
put_numeric_type(&mut self.out, scalar, &[size])?;
|
||||
write!(self.out, "(")?;
|
||||
put_expression(self, ctx, value)?;
|
||||
write!(self.out, ")")?;
|
||||
@ -1626,10 +1635,10 @@ impl<W: Write> Writer<W> {
|
||||
accept,
|
||||
reject,
|
||||
} => match *context.resolve_type(condition) {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if !is_scoped {
|
||||
write!(self.out, "(")?;
|
||||
}
|
||||
@ -1643,7 +1652,11 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {
|
||||
write!(self.out, "{NAMESPACE}::select(")?;
|
||||
@ -1687,7 +1700,7 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
let arg_type = context.resolve_type(arg);
|
||||
let scalar_argument = match arg_type {
|
||||
&crate::TypeInner::Scalar { .. } => true,
|
||||
&crate::TypeInner::Scalar(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
|
||||
@ -1732,7 +1745,11 @@ impl<W: Write> Writer<W> {
|
||||
// geometry
|
||||
Mf::Dot => match *context.resolve_type(arg) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => "dot",
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
@ -1838,16 +1855,16 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
// or metal will complain that select is ambiguous
|
||||
match *inner {
|
||||
crate::TypeInner::Vector { size, kind, .. } => {
|
||||
crate::TypeInner::Vector { size, scalar } => {
|
||||
let size = back::vector_size_str(size);
|
||||
if let crate::ScalarKind::Sint = kind {
|
||||
if let crate::ScalarKind::Sint = scalar.kind {
|
||||
write!(self.out, "int{size}")?;
|
||||
} else {
|
||||
write!(self.out, "uint{size}")?;
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar { kind, .. } => {
|
||||
if let crate::ScalarKind::Sint = kind {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
if let crate::ScalarKind::Sint = scalar.kind {
|
||||
write!(self.out, "int")?;
|
||||
} else {
|
||||
write!(self.out, "uint")?;
|
||||
@ -1893,19 +1910,15 @@ impl<W: Write> Writer<W> {
|
||||
kind,
|
||||
convert,
|
||||
} => match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
}
|
||||
| crate::TypeInner::Vector {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
..
|
||||
} => {
|
||||
crate::TypeInner::Scalar(src) | crate::TypeInner::Vector { scalar: src, .. } => {
|
||||
let target_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(src.width),
|
||||
};
|
||||
let is_bool_cast =
|
||||
kind == crate::ScalarKind::Bool || src_kind == crate::ScalarKind::Bool;
|
||||
kind == crate::ScalarKind::Bool || src.kind == crate::ScalarKind::Bool;
|
||||
let op = match convert {
|
||||
Some(w) if w == src_width || is_bool_cast => "static_cast",
|
||||
Some(w) if w == src.width || is_bool_cast => "static_cast",
|
||||
Some(8) if kind == crate::ScalarKind::Float => {
|
||||
return Err(Error::CapabilityNotSupported(valid::Capabilities::FLOAT64))
|
||||
}
|
||||
@ -1915,16 +1928,24 @@ impl<W: Write> Writer<W> {
|
||||
write!(self.out, "{op}<")?;
|
||||
match *context.resolve_type(expr) {
|
||||
crate::TypeInner::Vector { size, .. } => {
|
||||
put_numeric_type(&mut self.out, kind, &[size])?
|
||||
put_numeric_type(&mut self.out, target_scalar, &[size])?
|
||||
}
|
||||
_ => put_numeric_type(&mut self.out, kind, &[])?,
|
||||
_ => put_numeric_type(&mut self.out, target_scalar, &[])?,
|
||||
};
|
||||
write!(self.out, ">(")?;
|
||||
self.put_expression(expr, context, true)?;
|
||||
write!(self.out, ")")?;
|
||||
}
|
||||
crate::TypeInner::Matrix { columns, rows, .. } => {
|
||||
put_numeric_type(&mut self.out, kind, &[rows, columns])?;
|
||||
crate::TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
let target_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
put_numeric_type(&mut self.out, target_scalar, &[rows, columns])?;
|
||||
write!(self.out, "(")?;
|
||||
self.put_expression(expr, context, true)?;
|
||||
write!(self.out, ")")?;
|
||||
@ -2008,8 +2029,8 @@ impl<W: Write> Writer<W> {
|
||||
context: &ExpressionContext,
|
||||
is_scoped: bool,
|
||||
) -> BackendResult {
|
||||
if let Some(scalar_kind) = context.get_packed_vec_kind(expr_handle) {
|
||||
write!(self.out, "{}::{}3(", NAMESPACE, scalar_kind.to_msl_name())?;
|
||||
if let Some(scalar) = context.get_packed_vec_kind(expr_handle) {
|
||||
write!(self.out, "{}::{}3(", NAMESPACE, scalar.to_msl_name())?;
|
||||
self.put_expression(expr_handle, context, is_scoped)?;
|
||||
write!(self.out, ")")?;
|
||||
} else {
|
||||
@ -2475,8 +2496,8 @@ impl<W: Write> Writer<W> {
|
||||
// check what kind of product this is depending
|
||||
// on the resolve type of the Dot function itself
|
||||
let inner = context.resolve_type(expr_handle);
|
||||
if let crate::TypeInner::Scalar { kind, .. } = *inner {
|
||||
match kind {
|
||||
if let crate::TypeInner::Scalar(scalar) = *inner {
|
||||
match scalar.kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
self.need_bake_expressions.insert(arg);
|
||||
self.need_bake_expressions.insert(arg1.unwrap());
|
||||
@ -2522,14 +2543,19 @@ impl<W: Write> Writer<W> {
|
||||
};
|
||||
write!(self.out, "{ty_name}")?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Scalar { kind, .. }) => {
|
||||
put_numeric_type(&mut self.out, kind, &[])?;
|
||||
TypeResolution::Value(crate::TypeInner::Scalar(scalar)) => {
|
||||
put_numeric_type(&mut self.out, scalar, &[])?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Vector { size, kind, .. }) => {
|
||||
put_numeric_type(&mut self.out, kind, &[size])?;
|
||||
TypeResolution::Value(crate::TypeInner::Vector { size, scalar }) => {
|
||||
put_numeric_type(&mut self.out, scalar, &[size])?;
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Matrix { columns, rows, .. }) => {
|
||||
put_numeric_type(&mut self.out, crate::ScalarKind::Float, &[rows, columns])?;
|
||||
TypeResolution::Value(crate::TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width,
|
||||
}) => {
|
||||
let element = crate::Scalar::float(width);
|
||||
put_numeric_type(&mut self.out, element, &[rows, columns])?;
|
||||
}
|
||||
TypeResolution::Value(ref other) => {
|
||||
log::warn!("Type {:?} isn't a known local", other); //TEMP!
|
||||
@ -3292,13 +3318,13 @@ impl<W: Write> Writer<W> {
|
||||
|
||||
// If the member should be packed (as is the case for a misaligned vec3) issue a packed vector
|
||||
match should_pack_struct_member(members, span, index, module) {
|
||||
Some(kind) => {
|
||||
Some(scalar) => {
|
||||
writeln!(
|
||||
self.out,
|
||||
"{}{}::packed_{}3 {};",
|
||||
back::INDENT,
|
||||
NAMESPACE,
|
||||
kind.to_msl_name(),
|
||||
scalar.to_msl_name(),
|
||||
member_name
|
||||
)?;
|
||||
}
|
||||
@ -3322,11 +3348,10 @@ impl<W: Write> Writer<W> {
|
||||
// for 3-component vectors, add one component
|
||||
if let crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: _,
|
||||
width,
|
||||
scalar,
|
||||
} = *ty_inner
|
||||
{
|
||||
last_offset += width as u32;
|
||||
last_offset += scalar.width as u32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ use spirv::Word;
|
||||
|
||||
fn get_dimension(type_inner: &crate::TypeInner) -> Dimension {
|
||||
match *type_inner {
|
||||
crate::TypeInner::Scalar { .. } => Dimension::Scalar,
|
||||
crate::TypeInner::Scalar(_) => Dimension::Scalar,
|
||||
crate::TypeInner::Vector { .. } => Dimension::Vector,
|
||||
crate::TypeInner::Matrix { .. } => Dimension::Matrix,
|
||||
_ => unreachable!(),
|
||||
@ -78,8 +78,7 @@ impl Writer {
|
||||
) -> Result<(), Error> {
|
||||
let float_ptr_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: Some(spirv::StorageClass::Output),
|
||||
}));
|
||||
let index_y_id = self.get_index_constant(1);
|
||||
@ -93,8 +92,7 @@ impl Writer {
|
||||
|
||||
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let load_id = self.id_gen.next();
|
||||
@ -120,8 +118,7 @@ impl Writer {
|
||||
) -> Result<(), Error> {
|
||||
let float_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let zero_scalar_id = self.get_constant_scalar(crate::Literal::F32(0.0));
|
||||
@ -489,8 +486,8 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let spirv_op = match op {
|
||||
crate::BinaryOperator::Add => match *left_ty_inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
crate::ScalarKind::Float => spirv::Op::FAdd,
|
||||
_ => spirv::Op::IAdd,
|
||||
},
|
||||
@ -517,8 +514,8 @@ impl<'w> BlockContext<'w> {
|
||||
_ => unimplemented!(),
|
||||
},
|
||||
crate::BinaryOperator::Subtract => match *left_ty_inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
crate::ScalarKind::Float => spirv::Op::FSub,
|
||||
_ => spirv::Op::ISub,
|
||||
},
|
||||
@ -741,20 +738,19 @@ impl<'w> BlockContext<'w> {
|
||||
other => unimplemented!("Unexpected max({:?})", other),
|
||||
}),
|
||||
Mf::Saturate => {
|
||||
let (maybe_size, width) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => (Some(size), width),
|
||||
crate::TypeInner::Scalar { width, .. } => (None, width),
|
||||
let (maybe_size, scalar) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, scalar } => (Some(size), scalar),
|
||||
crate::TypeInner::Scalar(scalar) => (None, scalar),
|
||||
ref other => unimplemented!("Unexpected saturate({:?})", other),
|
||||
};
|
||||
let kind = crate::ScalarKind::Float;
|
||||
let mut arg1_id = self.writer.get_constant_scalar_with(0, kind, width)?;
|
||||
let mut arg2_id = self.writer.get_constant_scalar_with(1, kind, width)?;
|
||||
let scalar = crate::Scalar::float(scalar.width);
|
||||
let mut arg1_id = self.writer.get_constant_scalar_with(0, scalar)?;
|
||||
let mut arg2_id = self.writer.get_constant_scalar_with(1, scalar)?;
|
||||
|
||||
if let Some(size) = maybe_size {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -805,7 +801,11 @@ impl<'w> BlockContext<'w> {
|
||||
// geometry
|
||||
Mf::Dot => match *self.fun_info[arg].ty.inner_with(&self.ir_module.types) {
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => MathOp::Custom(Instruction::binary(
|
||||
spirv::Op::Dot,
|
||||
@ -866,13 +866,12 @@ impl<'w> BlockContext<'w> {
|
||||
// if the selector is a scalar, we need to splat it
|
||||
(
|
||||
&crate::TypeInner::Vector { size, .. },
|
||||
&crate::TypeInner::Scalar { kind, width },
|
||||
&crate::TypeInner::Scalar(scalar),
|
||||
) => {
|
||||
let selector_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
self.temp_list.clear();
|
||||
@ -915,14 +914,12 @@ impl<'w> BlockContext<'w> {
|
||||
arg0_id,
|
||||
)),
|
||||
Mf::CountTrailingZeros => {
|
||||
let kind = crate::ScalarKind::Uint;
|
||||
|
||||
let uint_id = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
crate::TypeInner::Vector { size, mut scalar } => {
|
||||
scalar.kind = crate::ScalarKind::Uint;
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -930,13 +927,14 @@ impl<'w> BlockContext<'w> {
|
||||
self.temp_list.clear();
|
||||
self.temp_list.resize(
|
||||
size as _,
|
||||
self.writer.get_constant_scalar_with(32, kind, width)?,
|
||||
self.writer.get_constant_scalar_with(32, scalar)?,
|
||||
);
|
||||
|
||||
self.writer.get_constant_composite(ty, &self.temp_list)
|
||||
}
|
||||
crate::TypeInner::Scalar { width, .. } => {
|
||||
self.writer.get_constant_scalar_with(32, kind, width)?
|
||||
crate::TypeInner::Scalar(mut scalar) => {
|
||||
scalar.kind = crate::ScalarKind::Uint;
|
||||
self.writer.get_constant_scalar_with(32, scalar)?
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -959,14 +957,12 @@ impl<'w> BlockContext<'w> {
|
||||
))
|
||||
}
|
||||
Mf::CountLeadingZeros => {
|
||||
let kind = crate::ScalarKind::Sint;
|
||||
|
||||
let (int_type_id, int_id) = match *arg_ty {
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
crate::TypeInner::Vector { size, mut scalar } => {
|
||||
scalar.kind = crate::ScalarKind::Sint;
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -974,7 +970,7 @@ impl<'w> BlockContext<'w> {
|
||||
self.temp_list.clear();
|
||||
self.temp_list.resize(
|
||||
size as _,
|
||||
self.writer.get_constant_scalar_with(31, kind, width)?,
|
||||
self.writer.get_constant_scalar_with(31, scalar)?,
|
||||
);
|
||||
|
||||
(
|
||||
@ -982,15 +978,17 @@ impl<'w> BlockContext<'w> {
|
||||
self.writer.get_constant_composite(ty, &self.temp_list),
|
||||
)
|
||||
}
|
||||
crate::TypeInner::Scalar { width, .. } => (
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
pointer_space: None,
|
||||
})),
|
||||
self.writer.get_constant_scalar_with(31, kind, width)?,
|
||||
),
|
||||
crate::TypeInner::Scalar(mut scalar) => {
|
||||
scalar.kind = crate::ScalarKind::Sint;
|
||||
(
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
})),
|
||||
self.writer.get_constant_scalar_with(31, scalar)?,
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -1139,13 +1137,13 @@ impl<'w> BlockContext<'w> {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let expr_id = self.cached[expr];
|
||||
let (src_kind, src_size, src_width, is_matrix) =
|
||||
let (src_scalar, src_size, is_matrix) =
|
||||
match *self.fun_info[expr].ty.inner_with(&self.ir_module.types) {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, None, width, false),
|
||||
crate::TypeInner::Vector { kind, width, size } => {
|
||||
(kind, Some(size), width, false)
|
||||
crate::TypeInner::Scalar(scalar) => (scalar, None, false),
|
||||
crate::TypeInner::Vector { scalar, size } => (scalar, Some(size), false),
|
||||
crate::TypeInner::Matrix { width, .. } => {
|
||||
(crate::Scalar::float(width), None, true)
|
||||
}
|
||||
crate::TypeInner::Matrix { width, .. } => (kind, None, width, true),
|
||||
ref other => {
|
||||
log::error!("As source {:?}", other);
|
||||
return Err(Error::Validation("Unexpected Expression::As source"));
|
||||
@ -1163,11 +1161,12 @@ impl<'w> BlockContext<'w> {
|
||||
// we only support identity casts for matrices
|
||||
Cast::Unary(spirv::Op::CopyObject)
|
||||
} else {
|
||||
match (src_kind, kind, convert) {
|
||||
match (src_scalar.kind, kind, convert) {
|
||||
// Filter out identity casts. Some Adreno drivers are
|
||||
// confused by no-op OpBitCast instructions.
|
||||
(src_kind, kind, convert)
|
||||
if src_kind == kind && convert.unwrap_or(src_width) == src_width =>
|
||||
if src_kind == kind
|
||||
&& convert.filter(|&width| width != src_scalar.width).is_none() =>
|
||||
{
|
||||
Cast::Identity
|
||||
}
|
||||
@ -1175,20 +1174,18 @@ impl<'w> BlockContext<'w> {
|
||||
(_, _, None) => Cast::Unary(spirv::Op::Bitcast),
|
||||
// casting to a bool - generate `OpXxxNotEqual`
|
||||
(_, Sk::Bool, Some(_)) => {
|
||||
let op = match src_kind {
|
||||
let op = match src_scalar.kind {
|
||||
Sk::Sint | Sk::Uint => spirv::Op::INotEqual,
|
||||
Sk::Float => spirv::Op::FUnordNotEqual,
|
||||
Sk::Bool => unreachable!(),
|
||||
};
|
||||
let zero_scalar_id = self
|
||||
.writer
|
||||
.get_constant_scalar_with(0, src_kind, src_width)?;
|
||||
let zero_scalar_id =
|
||||
self.writer.get_constant_scalar_with(0, src_scalar)?;
|
||||
let zero_id = match src_size {
|
||||
Some(size) => {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
scalar: src_scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -1205,16 +1202,19 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
// casting from a bool - generate `OpSelect`
|
||||
(Sk::Bool, _, Some(dst_width)) => {
|
||||
let dst_scalar = crate::Scalar {
|
||||
kind,
|
||||
width: dst_width,
|
||||
};
|
||||
let zero_scalar_id =
|
||||
self.writer.get_constant_scalar_with(0, kind, dst_width)?;
|
||||
self.writer.get_constant_scalar_with(0, dst_scalar)?;
|
||||
let one_scalar_id =
|
||||
self.writer.get_constant_scalar_with(1, kind, dst_width)?;
|
||||
self.writer.get_constant_scalar_with(1, dst_scalar)?;
|
||||
let (accept_id, reject_id) = match src_size {
|
||||
Some(size) => {
|
||||
let ty = LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
pointer_space: None,
|
||||
}
|
||||
.into();
|
||||
@ -1239,15 +1239,17 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
(Sk::Float, Sk::Uint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToU),
|
||||
(Sk::Float, Sk::Sint, Some(_)) => Cast::Unary(spirv::Op::ConvertFToS),
|
||||
(Sk::Float, Sk::Float, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Float, Sk::Float, Some(dst_width))
|
||||
if src_scalar.width != dst_width =>
|
||||
{
|
||||
Cast::Unary(spirv::Op::FConvert)
|
||||
}
|
||||
(Sk::Sint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertSToF),
|
||||
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Sint, Sk::Sint, Some(dst_width)) if src_scalar.width != dst_width => {
|
||||
Cast::Unary(spirv::Op::SConvert)
|
||||
}
|
||||
(Sk::Uint, Sk::Float, Some(_)) => Cast::Unary(spirv::Op::ConvertUToF),
|
||||
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_width != dst_width => {
|
||||
(Sk::Uint, Sk::Uint, Some(dst_width)) if src_scalar.width != dst_width => {
|
||||
Cast::Unary(spirv::Op::UConvert)
|
||||
}
|
||||
// We assume it's either an identity cast, or int-uint.
|
||||
@ -1334,10 +1336,12 @@ impl<'w> BlockContext<'w> {
|
||||
let object_ty = self.fun_info[accept].ty.inner_with(&self.ir_module.types);
|
||||
|
||||
if let (
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width,
|
||||
},
|
||||
&crate::TypeInner::Scalar(
|
||||
condition_scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
},
|
||||
),
|
||||
&crate::TypeInner::Vector { size, .. },
|
||||
) = (condition_ty, object_ty)
|
||||
{
|
||||
@ -1347,8 +1351,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_vector_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width,
|
||||
scalar: condition_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1598,8 +1601,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let vector_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1649,7 +1651,10 @@ impl<'w> BlockContext<'w> {
|
||||
vector: &crate::TypeInner,
|
||||
) {
|
||||
let (size, kind) = match *vector {
|
||||
crate::TypeInner::Vector { size, kind, .. } => (size, kind),
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { kind, .. },
|
||||
} => (size, kind),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
@ -2193,14 +2198,14 @@ impl<'w> BlockContext<'w> {
|
||||
),
|
||||
crate::AtomicFunction::Min => {
|
||||
let spirv_op = match *value_inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicSMin,
|
||||
crate::TypeInner::Scalar {
|
||||
}) => spirv::Op::AtomicSMin,
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicUMin,
|
||||
}) => spirv::Op::AtomicUMin,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Instruction::atomic_binary(
|
||||
@ -2215,14 +2220,14 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
crate::AtomicFunction::Max => {
|
||||
let spirv_op = match *value_inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicSMax,
|
||||
crate::TypeInner::Scalar {
|
||||
}) => spirv::Op::AtomicSMax,
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => spirv::Op::AtomicUMax,
|
||||
}) => spirv::Op::AtomicUMax,
|
||||
_ => unimplemented!(),
|
||||
};
|
||||
Instruction::atomic_binary(
|
||||
@ -2248,11 +2253,10 @@ impl<'w> BlockContext<'w> {
|
||||
}
|
||||
crate::AtomicFunction::Exchange { compare: Some(cmp) } => {
|
||||
let scalar_type_id = match *value_inner {
|
||||
crate::TypeInner::Scalar { kind, width } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}))
|
||||
}
|
||||
@ -2261,8 +2265,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_type_id =
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
|
@ -128,8 +128,7 @@ impl Load {
|
||||
crate::ImageClass::Depth { .. } => {
|
||||
ctx.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Quad),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}))
|
||||
}
|
||||
@ -292,18 +291,16 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
// Find the component type of `coordinates`, and figure out the size the
|
||||
// combined coordinate vector will have.
|
||||
let (component_kind, size) = match *inner_ty {
|
||||
Ti::Scalar { kind, width: 4 } => (kind, Some(Vs::Bi)),
|
||||
let (component_scalar, size) = match *inner_ty {
|
||||
Ti::Scalar(scalar @ crate::Scalar { width: 4, .. }) => (scalar, Some(Vs::Bi)),
|
||||
Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
size: Vs::Bi,
|
||||
} => (kind, Some(Vs::Tri)),
|
||||
} => (scalar, Some(Vs::Tri)),
|
||||
Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: scalar @ crate::Scalar { width: 4, .. },
|
||||
size: Vs::Tri,
|
||||
} => (kind, Some(Vs::Quad)),
|
||||
} => (scalar, Some(Vs::Quad)),
|
||||
Ti::Vector { size: Vs::Quad, .. } => {
|
||||
return Err(Error::Validation("extending vec4 coordinate"));
|
||||
}
|
||||
@ -317,16 +314,16 @@ impl<'w> BlockContext<'w> {
|
||||
let array_index_id = self.cached[array_index];
|
||||
let ty = &self.fun_info[array_index].ty;
|
||||
let inner_ty = ty.inner_with(&self.ir_module.types);
|
||||
let array_index_kind = if let Ti::Scalar { kind, width: 4 } = *inner_ty {
|
||||
debug_assert!(matches!(
|
||||
kind,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint
|
||||
));
|
||||
kind
|
||||
} else {
|
||||
unreachable!("we only allow i32 and u32");
|
||||
let array_index_scalar = match *inner_ty {
|
||||
Ti::Scalar(
|
||||
scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
) => scalar,
|
||||
_ => unreachable!("we only allow i32 and u32"),
|
||||
};
|
||||
let cast = match (component_kind, array_index_kind) {
|
||||
let cast = match (component_scalar.kind, array_index_scalar.kind) {
|
||||
(crate::ScalarKind::Sint, crate::ScalarKind::Sint)
|
||||
| (crate::ScalarKind::Uint, crate::ScalarKind::Uint) => None,
|
||||
(crate::ScalarKind::Sint, crate::ScalarKind::Uint)
|
||||
@ -341,8 +338,7 @@ impl<'w> BlockContext<'w> {
|
||||
let reconciled_array_index_id = if let Some(cast) = cast {
|
||||
let component_ty_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: component_kind,
|
||||
width: 4,
|
||||
scalar: component_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let reconciled_id = self.gen_id();
|
||||
@ -360,8 +356,7 @@ impl<'w> BlockContext<'w> {
|
||||
// Find the SPIR-V type for the combined coordinates/index vector.
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: size,
|
||||
kind: component_kind,
|
||||
width: 4,
|
||||
scalar: component_scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -532,8 +527,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -620,8 +614,7 @@ impl<'w> BlockContext<'w> {
|
||||
let bool_type_id = self.writer.get_bool_type_id();
|
||||
let i32_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::I32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -688,8 +681,7 @@ impl<'w> BlockContext<'w> {
|
||||
// Compare the coordinates against the bounds.
|
||||
let coords_bool_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: coordinates.size,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let coords_conds_id = self.gen_id();
|
||||
@ -844,8 +836,7 @@ impl<'w> BlockContext<'w> {
|
||||
let sample_result_type_id = if needs_sub_access {
|
||||
self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Quad),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}))
|
||||
} else {
|
||||
@ -1045,8 +1036,7 @@ impl<'w> BlockContext<'w> {
|
||||
};
|
||||
let extended_size_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
|
||||
@ -1116,8 +1106,7 @@ impl<'w> BlockContext<'w> {
|
||||
};
|
||||
let extended_size_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(vec_size),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let id_extended = self.gen_id();
|
||||
|
@ -276,8 +276,7 @@ enum LocalType {
|
||||
/// If `None`, this represents a scalar type. If `Some`, this represents
|
||||
/// a vector type of the given size.
|
||||
vector_size: Option<crate::VectorSize>,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: crate::Scalar,
|
||||
pointer_space: Option<spirv::StorageClass>,
|
||||
},
|
||||
/// A matrix of floating-point values.
|
||||
@ -355,18 +354,14 @@ struct LookupFunctionType {
|
||||
|
||||
fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
|
||||
Some(match *inner {
|
||||
crate::TypeInner::Scalar { kind, width } | crate::TypeInner::Atomic { kind, width } => {
|
||||
LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
pointer_space: None,
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Vector { size, kind, width } => LocalType::Value {
|
||||
crate::TypeInner::Scalar(scalar) | crate::TypeInner::Atomic(scalar) => LocalType::Value {
|
||||
vector_size: None,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
},
|
||||
crate::TypeInner::Vector { size, scalar } => LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
},
|
||||
crate::TypeInner::Matrix {
|
||||
@ -384,13 +379,11 @@ fn make_local(inner: &crate::TypeInner) -> Option<LocalType> {
|
||||
},
|
||||
crate::TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => LocalType::Value {
|
||||
vector_size: size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: Some(helpers::map_storage_class(space)),
|
||||
},
|
||||
crate::TypeInner::Image {
|
||||
|
@ -21,12 +21,10 @@ impl<'w> BlockContext<'w> {
|
||||
//Note: composite extract indices and types must match `generate_ray_desc_type`
|
||||
let desc_id = self.cached[descriptor];
|
||||
let acc_struct_id = self.get_handle_id(acceleration_structure);
|
||||
let width = 4;
|
||||
|
||||
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let ray_flags_id = self.gen_id();
|
||||
@ -46,8 +44,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let tmin_id = self.gen_id();
|
||||
@ -67,8 +64,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let vector_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let ray_origin_id = self.gen_id();
|
||||
@ -115,7 +111,6 @@ impl<'w> BlockContext<'w> {
|
||||
query: Handle<crate::Expression>,
|
||||
block: &mut Block,
|
||||
) -> spirv::Word {
|
||||
let width = 4;
|
||||
let query_id = self.cached[query];
|
||||
let intersection_id = self.writer.get_constant_scalar(crate::Literal::U32(
|
||||
spirv::RayQueryIntersection::RayQueryCommittedIntersectionKHR as _,
|
||||
@ -123,8 +118,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let flag_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let kind_id = self.gen_id();
|
||||
@ -178,8 +172,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let scalar_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let t_id = self.gen_id();
|
||||
@ -193,8 +186,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let barycentrics_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Bi),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let barycentrics_id = self.gen_id();
|
||||
@ -208,8 +200,7 @@ impl<'w> BlockContext<'w> {
|
||||
|
||||
let bool_type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
}));
|
||||
let front_face_id = self.gen_id();
|
||||
@ -224,7 +215,7 @@ impl<'w> BlockContext<'w> {
|
||||
let transform_type_id = self.get_type_id(LookupType::Local(LocalType::Matrix {
|
||||
columns: crate::VectorSize::Quad,
|
||||
rows: crate::VectorSize::Tri,
|
||||
width,
|
||||
width: 4,
|
||||
}));
|
||||
let object_to_world_id = self.gen_id();
|
||||
block.body.push(Instruction::ray_query_get_intersection(
|
||||
|
@ -238,8 +238,7 @@ impl Writer {
|
||||
pub(super) fn get_uint_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -248,8 +247,7 @@ impl Writer {
|
||||
pub(super) fn get_float_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -258,8 +256,7 @@ impl Writer {
|
||||
pub(super) fn get_uint3_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -268,8 +265,7 @@ impl Writer {
|
||||
pub(super) fn get_float_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
|
||||
let lookup_type = LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
pointer_space: Some(class),
|
||||
});
|
||||
if let Some(&id) = self.lookup_type.get(&lookup_type) {
|
||||
@ -287,8 +283,7 @@ impl Writer {
|
||||
pub(super) fn get_uint3_pointer_type_id(&mut self, class: spirv::StorageClass) -> Word {
|
||||
let lookup_type = LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
pointer_space: Some(class),
|
||||
});
|
||||
if let Some(&id) = self.lookup_type.get(&lookup_type) {
|
||||
@ -306,8 +301,7 @@ impl Writer {
|
||||
pub(super) fn get_bool_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -316,8 +310,7 @@ impl Writer {
|
||||
pub(super) fn get_bool3_type_id(&mut self) -> Word {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: Some(crate::VectorSize::Tri),
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 1,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
pointer_space: None,
|
||||
};
|
||||
self.get_type_id(local_type.into())
|
||||
@ -802,18 +795,13 @@ impl Writer {
|
||||
))
|
||||
}
|
||||
|
||||
fn make_scalar(
|
||||
&mut self,
|
||||
id: Word,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Instruction {
|
||||
fn make_scalar(&mut self, id: Word, scalar: crate::Scalar) -> Instruction {
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let bits = (width * BITS_PER_BYTE) as u32;
|
||||
match kind {
|
||||
let bits = (scalar.width * BITS_PER_BYTE) as u32;
|
||||
match scalar.kind {
|
||||
Sk::Sint | Sk::Uint => {
|
||||
let signedness = if kind == Sk::Sint {
|
||||
let signedness = if scalar.kind == Sk::Sint {
|
||||
super::instructions::Signedness::Signed
|
||||
} else {
|
||||
super::instructions::Signedness::Unsigned
|
||||
@ -894,20 +882,17 @@ impl Writer {
|
||||
let instruction = match local_ty {
|
||||
LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
} => self.make_scalar(id, kind, width),
|
||||
} => self.make_scalar(id, scalar),
|
||||
LocalType::Value {
|
||||
vector_size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
} => {
|
||||
let scalar_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_vector(id, scalar_id, size)
|
||||
@ -919,8 +904,7 @@ impl Writer {
|
||||
} => {
|
||||
let vector_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_matrix(id, vector_id, columns)
|
||||
@ -931,14 +915,12 @@ impl Writer {
|
||||
}
|
||||
LocalType::Value {
|
||||
vector_size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: Some(class),
|
||||
} => {
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
pointer_space: None,
|
||||
}));
|
||||
Instruction::type_pointer(id, class, type_id)
|
||||
@ -946,8 +928,10 @@ impl Writer {
|
||||
LocalType::Image(image) => {
|
||||
let local_type = LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: image.sampled_type,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: image.sampled_type,
|
||||
width: 4,
|
||||
},
|
||||
pointer_space: None,
|
||||
};
|
||||
let type_id = self.get_type_id(LookupType::Local(local_type));
|
||||
@ -1060,8 +1044,8 @@ impl Writer {
|
||||
|
||||
// These all have TypeLocal representations, so they should have been
|
||||
// handled by `write_type_declaration_local` above.
|
||||
crate::TypeInner::Scalar { .. }
|
||||
| crate::TypeInner::Atomic { .. }
|
||||
crate::TypeInner::Scalar(_)
|
||||
| crate::TypeInner::Atomic(_)
|
||||
| crate::TypeInner::Vector { .. }
|
||||
| crate::TypeInner::Matrix { .. }
|
||||
| crate::TypeInner::Pointer { .. }
|
||||
@ -1151,11 +1135,10 @@ impl Writer {
|
||||
pub(super) fn get_constant_scalar_with(
|
||||
&mut self,
|
||||
value: u8,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: crate::Scalar,
|
||||
) -> Result<Word, Error> {
|
||||
Ok(
|
||||
self.get_constant_scalar(crate::Literal::new(value, kind, width).ok_or(
|
||||
self.get_constant_scalar(crate::Literal::new(value, scalar).ok_or(
|
||||
Error::Validation("Unexpected kind and/or width for Literal"),
|
||||
)?),
|
||||
)
|
||||
@ -1185,8 +1168,7 @@ impl Writer {
|
||||
}
|
||||
let type_id = self.get_type_id(LookupType::Local(LocalType::Value {
|
||||
vector_size: None,
|
||||
kind: value.scalar_kind(),
|
||||
width: value.width(),
|
||||
scalar: value.scalar(),
|
||||
pointer_space: None,
|
||||
}));
|
||||
let instruction = match *value {
|
||||
@ -1602,8 +1584,8 @@ impl Writer {
|
||||
// > shader, must be decorated Flat
|
||||
if class == spirv::StorageClass::Input && stage == crate::ShaderStage::Fragment {
|
||||
let is_flat = match ir_module.types[ty].inner {
|
||||
crate::TypeInner::Scalar { kind, .. }
|
||||
| crate::TypeInner::Vector { kind, .. } => match kind {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Bool => true,
|
||||
Sk::Float => false,
|
||||
},
|
||||
|
@ -426,11 +426,11 @@ impl<W: Write> Writer<W> {
|
||||
/// Adds no trailing or leading whitespace
|
||||
fn write_value_type(&mut self, module: &Module, inner: &TypeInner) -> BackendResult {
|
||||
match *inner {
|
||||
TypeInner::Vector { size, kind, width } => write!(
|
||||
TypeInner::Vector { size, scalar } => write!(
|
||||
self.out,
|
||||
"vec{}<{}>",
|
||||
back::vector_size_str(size),
|
||||
scalar_kind_str(kind, width),
|
||||
scalar_kind_str(scalar),
|
||||
)?,
|
||||
TypeInner::Sampler { comparison: false } => {
|
||||
write!(self.out, "sampler")?;
|
||||
@ -452,7 +452,7 @@ impl<W: Write> Writer<W> {
|
||||
Ic::Sampled { kind, multi } => (
|
||||
"",
|
||||
if multi { "multisampled_" } else { "" },
|
||||
scalar_kind_str(kind, 4),
|
||||
scalar_kind_str(crate::Scalar { kind, width: 4 }),
|
||||
"",
|
||||
),
|
||||
Ic::Depth { multi } => {
|
||||
@ -481,11 +481,11 @@ impl<W: Write> Writer<W> {
|
||||
write!(self.out, "<{format_str}{storage_str}>")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
write!(self.out, "{}", scalar_kind_str(kind, width))?;
|
||||
TypeInner::Scalar(scalar) => {
|
||||
write!(self.out, "{}", scalar_kind_str(scalar))?;
|
||||
}
|
||||
TypeInner::Atomic { kind, width } => {
|
||||
write!(self.out, "atomic<{}>", scalar_kind_str(kind, width))?;
|
||||
TypeInner::Atomic(scalar) => {
|
||||
write!(self.out, "atomic<{}>", scalar_kind_str(scalar))?;
|
||||
}
|
||||
TypeInner::Array {
|
||||
base,
|
||||
@ -552,13 +552,12 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
let (address, maybe_access) = address_space_str(space);
|
||||
if let Some(space) = address {
|
||||
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(kind, width))?;
|
||||
write!(self.out, "ptr<{}, {}", space, scalar_kind_str(scalar))?;
|
||||
if let Some(access) = maybe_access {
|
||||
write!(self.out, ", {access}")?;
|
||||
}
|
||||
@ -571,8 +570,7 @@ impl<W: Write> Writer<W> {
|
||||
}
|
||||
TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
let (address, maybe_access) = address_space_str(space);
|
||||
@ -582,7 +580,7 @@ impl<W: Write> Writer<W> {
|
||||
"ptr<{}, vec{}<{}>",
|
||||
space,
|
||||
back::vector_size_str(size),
|
||||
scalar_kind_str(kind, width)
|
||||
scalar_kind_str(scalar)
|
||||
)?;
|
||||
if let Some(access) = maybe_access {
|
||||
write!(self.out, ", {access}")?;
|
||||
@ -1414,7 +1412,11 @@ impl<W: Write> Writer<W> {
|
||||
width,
|
||||
..
|
||||
} => {
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
write!(
|
||||
self.out,
|
||||
"mat{}x{}<{}>",
|
||||
@ -1423,17 +1425,28 @@ impl<W: Write> Writer<W> {
|
||||
scalar_kind_str
|
||||
)?;
|
||||
}
|
||||
TypeInner::Vector { size, width, .. } => {
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { width, .. },
|
||||
} => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let vector_size_str = back::vector_size_str(size);
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
if convert.is_some() {
|
||||
write!(self.out, "vec{vector_size_str}<{scalar_kind_str}>")?;
|
||||
} else {
|
||||
write!(self.out, "bitcast<vec{vector_size_str}<{scalar_kind_str}>>")?;
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { width, .. } => {
|
||||
let scalar_kind_str = scalar_kind_str(kind, convert.unwrap_or(width));
|
||||
TypeInner::Scalar(crate::Scalar { width, .. }) => {
|
||||
let scalar = crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
};
|
||||
let scalar_kind_str = scalar_kind_str(scalar);
|
||||
if convert.is_some() {
|
||||
write!(self.out, "{scalar_kind_str}")?
|
||||
} else {
|
||||
@ -1783,15 +1796,31 @@ const fn image_dimension_str(dim: crate::ImageDimension) -> &'static str {
|
||||
}
|
||||
}
|
||||
|
||||
const fn scalar_kind_str(kind: crate::ScalarKind, width: u8) -> &'static str {
|
||||
const fn scalar_kind_str(scalar: crate::Scalar) -> &'static str {
|
||||
use crate::Scalar;
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
match (kind, width) {
|
||||
(Sk::Float, 8) => "f64",
|
||||
(Sk::Float, 4) => "f32",
|
||||
(Sk::Sint, 4) => "i32",
|
||||
(Sk::Uint, 4) => "u32",
|
||||
(Sk::Bool, 1) => "bool",
|
||||
match scalar {
|
||||
Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 8,
|
||||
} => "f64",
|
||||
Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
} => "f32",
|
||||
Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
} => "i32",
|
||||
Scalar {
|
||||
kind: Sk::Uint,
|
||||
width: 4,
|
||||
} => "u32",
|
||||
Scalar {
|
||||
kind: Sk::Bool,
|
||||
width: 1,
|
||||
} => "bool",
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -54,10 +54,10 @@ impl ModuleMap {
|
||||
use crate::TypeInner as Ti;
|
||||
match ty.inner {
|
||||
// Types that do not contain handles.
|
||||
Ti::Scalar { .. }
|
||||
Ti::Scalar(_)
|
||||
| Ti::Vector { .. }
|
||||
| Ti::Matrix { .. }
|
||||
| Ti::Atomic { .. }
|
||||
| Ti::Atomic(_)
|
||||
| Ti::ValuePointer { .. }
|
||||
| Ti::Image { .. }
|
||||
| Ti::Sampler { .. }
|
||||
|
@ -9,7 +9,7 @@ use super::{
|
||||
use crate::{
|
||||
BinaryOperator, DerivativeAxis as Axis, DerivativeControl as Ctrl, Expression, Handle,
|
||||
ImageClass, ImageDimension as Dim, ImageQuery, MathFunction, Module, RelationalFunction,
|
||||
SampleLevel, ScalarKind as Sk, Span, Type, TypeInner, UnaryOperator, VectorSize,
|
||||
SampleLevel, Scalar, ScalarKind as Sk, Span, Type, TypeInner, UnaryOperator, VectorSize,
|
||||
};
|
||||
|
||||
impl crate::ScalarKind {
|
||||
@ -54,18 +54,17 @@ impl Module {
|
||||
}
|
||||
|
||||
const fn make_coords_arg(number_of_components: usize, kind: Sk) -> TypeInner {
|
||||
let width = 4;
|
||||
let scalar = Scalar { kind, width: 4 };
|
||||
|
||||
match number_of_components {
|
||||
1 => TypeInner::Scalar { kind, width },
|
||||
1 => TypeInner::Scalar(scalar),
|
||||
_ => TypeInner::Vector {
|
||||
size: match number_of_components {
|
||||
2 => VectorSize::Bi,
|
||||
3 => VectorSize::Tri,
|
||||
_ => VectorSize::Quad,
|
||||
},
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -98,7 +97,6 @@ pub fn inject_builtin(
|
||||
inject_double_builtin(declaration, module, name)
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
match name {
|
||||
"texture"
|
||||
| "textureGrad"
|
||||
@ -235,18 +233,12 @@ pub fn inject_builtin(
|
||||
let mut args = vec![image, vector];
|
||||
|
||||
if num_coords == 5 {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
|
||||
match level_type {
|
||||
TextureLevelType::Lod => {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
TextureLevelType::Grad => {
|
||||
args.push(make_coords_arg(num_coords_from_dim, Sk::Float));
|
||||
@ -260,10 +252,7 @@ pub fn inject_builtin(
|
||||
}
|
||||
|
||||
if bias {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::F32));
|
||||
}
|
||||
|
||||
declaration
|
||||
@ -290,10 +279,7 @@ pub fn inject_builtin(
|
||||
let mut args = vec![image];
|
||||
|
||||
if !multi {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
})
|
||||
args.push(TypeInner::Scalar(Scalar::I32))
|
||||
}
|
||||
|
||||
declaration
|
||||
@ -323,14 +309,7 @@ pub fn inject_builtin(
|
||||
let dim_value = image_dims_to_coords_size(dim);
|
||||
let coordinates = make_coords_arg(dim_value + arrayed as usize, Sk::Sint);
|
||||
|
||||
let mut args = vec![
|
||||
image,
|
||||
coordinates,
|
||||
TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
},
|
||||
];
|
||||
let mut args = vec![image, coordinates, TypeInner::Scalar(Scalar::I32)];
|
||||
|
||||
if offset {
|
||||
args.push(make_coords_arg(dim_value, Sk::Sint));
|
||||
@ -441,8 +420,7 @@ pub fn inject_builtin(
|
||||
coordinates,
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind,
|
||||
width,
|
||||
scalar: Scalar { kind, width: 4 },
|
||||
},
|
||||
];
|
||||
|
||||
@ -464,7 +442,6 @@ fn inject_standard_builtins(
|
||||
module: &mut Module,
|
||||
name: &str,
|
||||
) {
|
||||
let width = 4;
|
||||
match name {
|
||||
"sampler1D" | "sampler1DArray" | "sampler2D" | "sampler2DArray" | "sampler2DMS"
|
||||
| "sampler2DMSArray" | "sampler3D" | "samplerCube" | "samplerCubeArray" => {
|
||||
@ -544,12 +521,12 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}],
|
||||
match name {
|
||||
"sin" => MacroCall::MathFunction(MathFunction::Sin),
|
||||
@ -595,15 +572,15 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = match name {
|
||||
"intBitsToFloat" => Sk::Sint,
|
||||
_ => Sk::Uint,
|
||||
let scalar = match name {
|
||||
"intBitsToFloat" => Scalar::I32,
|
||||
_ => Scalar::U32,
|
||||
};
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}],
|
||||
MacroCall::BitCast(Sk::Float),
|
||||
))
|
||||
@ -619,10 +596,10 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
declaration.overloads.push(
|
||||
@ -642,14 +619,14 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = match bits >> 2 {
|
||||
0b0 => Sk::Float,
|
||||
_ => Sk::Sint,
|
||||
let scalar = match bits >> 2 {
|
||||
0b0 => Scalar::F32,
|
||||
_ => Scalar::I32,
|
||||
};
|
||||
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}];
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -684,9 +661,9 @@ fn inject_standard_builtins(
|
||||
// bit 0 - int/uint
|
||||
// bit 1 through 2 - dims
|
||||
for bits in 0..0b1000 {
|
||||
let kind = match bits & 0b1 {
|
||||
0b0 => Sk::Sint,
|
||||
_ => Sk::Uint,
|
||||
let scalar = match bits & 0b1 {
|
||||
0b0 => Scalar::I32,
|
||||
_ => Scalar::U32,
|
||||
};
|
||||
let size = match bits >> 1 {
|
||||
0b00 => None,
|
||||
@ -696,39 +673,27 @@ fn inject_standard_builtins(
|
||||
};
|
||||
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let mut args = vec![ty()];
|
||||
|
||||
match fun {
|
||||
MathFunction::ExtractBits => {
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
}
|
||||
MathFunction::InsertBits => {
|
||||
args.push(ty());
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
});
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
args.push(TypeInner::Scalar(Scalar::I32));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// we need to cast the return type of findLsb / findMsb
|
||||
let mc = if kind == Sk::Uint {
|
||||
let mc = if scalar.kind == Sk::Uint {
|
||||
match mc {
|
||||
MacroCall::MathFunction(MathFunction::FindLsb) => MacroCall::FindLsbUint,
|
||||
MacroCall::MathFunction(MathFunction::FindMsb) => MacroCall::FindMsbUint,
|
||||
@ -754,15 +719,13 @@ fn inject_standard_builtins(
|
||||
let ty = match fun {
|
||||
MathFunction::Pack4x8snorm | MathFunction::Pack4x8unorm => TypeInner::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
MathFunction::Pack2x16unorm
|
||||
| MathFunction::Pack2x16snorm
|
||||
| MathFunction::Pack2x16float => TypeInner::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
_ => unreachable!(),
|
||||
};
|
||||
@ -784,10 +747,7 @@ fn inject_standard_builtins(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let args = vec![TypeInner::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width: 4,
|
||||
}];
|
||||
let args = vec![TypeInner::Scalar(Scalar::U32)];
|
||||
|
||||
declaration
|
||||
.overloads
|
||||
@ -808,10 +768,10 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F32;
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let mut args = vec![ty()];
|
||||
@ -837,8 +797,7 @@ fn inject_standard_builtins(
|
||||
|
||||
let args = vec![TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: Scalar::BOOL,
|
||||
}];
|
||||
|
||||
let fun = match name {
|
||||
@ -853,19 +812,19 @@ fn inject_standard_builtins(
|
||||
}
|
||||
"lessThan" | "greaterThan" | "lessThanEqual" | "greaterThanEqual" => {
|
||||
for bits in 0..0b1001 {
|
||||
let (size, kind) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Sk::Float),
|
||||
0b0001 => (VectorSize::Tri, Sk::Float),
|
||||
0b0010 => (VectorSize::Quad, Sk::Float),
|
||||
0b0011 => (VectorSize::Bi, Sk::Sint),
|
||||
0b0100 => (VectorSize::Tri, Sk::Sint),
|
||||
0b0101 => (VectorSize::Quad, Sk::Sint),
|
||||
0b0110 => (VectorSize::Bi, Sk::Uint),
|
||||
0b0111 => (VectorSize::Tri, Sk::Uint),
|
||||
_ => (VectorSize::Quad, Sk::Uint),
|
||||
let (size, scalar) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Scalar::F32),
|
||||
0b0001 => (VectorSize::Tri, Scalar::F32),
|
||||
0b0010 => (VectorSize::Quad, Scalar::F32),
|
||||
0b0011 => (VectorSize::Bi, Scalar::I32),
|
||||
0b0100 => (VectorSize::Tri, Scalar::I32),
|
||||
0b0101 => (VectorSize::Quad, Scalar::I32),
|
||||
0b0110 => (VectorSize::Bi, Scalar::U32),
|
||||
0b0111 => (VectorSize::Tri, Scalar::U32),
|
||||
_ => (VectorSize::Quad, Scalar::U32),
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -881,28 +840,22 @@ fn inject_standard_builtins(
|
||||
}
|
||||
"equal" | "notEqual" => {
|
||||
for bits in 0..0b1100 {
|
||||
let (size, kind) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Sk::Float),
|
||||
0b0001 => (VectorSize::Tri, Sk::Float),
|
||||
0b0010 => (VectorSize::Quad, Sk::Float),
|
||||
0b0011 => (VectorSize::Bi, Sk::Sint),
|
||||
0b0100 => (VectorSize::Tri, Sk::Sint),
|
||||
0b0101 => (VectorSize::Quad, Sk::Sint),
|
||||
0b0110 => (VectorSize::Bi, Sk::Uint),
|
||||
0b0111 => (VectorSize::Tri, Sk::Uint),
|
||||
0b1000 => (VectorSize::Quad, Sk::Uint),
|
||||
0b1001 => (VectorSize::Bi, Sk::Bool),
|
||||
0b1010 => (VectorSize::Tri, Sk::Bool),
|
||||
_ => (VectorSize::Quad, Sk::Bool),
|
||||
let (size, scalar) = match bits {
|
||||
0b0000 => (VectorSize::Bi, Scalar::F32),
|
||||
0b0001 => (VectorSize::Tri, Scalar::F32),
|
||||
0b0010 => (VectorSize::Quad, Scalar::F32),
|
||||
0b0011 => (VectorSize::Bi, Scalar::I32),
|
||||
0b0100 => (VectorSize::Tri, Scalar::I32),
|
||||
0b0101 => (VectorSize::Quad, Scalar::I32),
|
||||
0b0110 => (VectorSize::Bi, Scalar::U32),
|
||||
0b0111 => (VectorSize::Tri, Scalar::U32),
|
||||
0b1000 => (VectorSize::Quad, Scalar::U32),
|
||||
0b1001 => (VectorSize::Bi, Scalar::BOOL),
|
||||
0b1010 => (VectorSize::Tri, Scalar::BOOL),
|
||||
_ => (VectorSize::Quad, Scalar::BOOL),
|
||||
};
|
||||
|
||||
let width = if let Sk::Bool = kind {
|
||||
crate::BOOL_WIDTH
|
||||
} else {
|
||||
width
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -919,10 +872,10 @@ fn inject_standard_builtins(
|
||||
// bit 0 through 1 - scalar kind
|
||||
// bit 2 through 4 - dims
|
||||
for bits in 0..0b11100 {
|
||||
let kind = match bits & 0b11 {
|
||||
0b00 => Sk::Float,
|
||||
0b01 => Sk::Sint,
|
||||
0b10 => Sk::Uint,
|
||||
let scalar = match bits & 0b11 {
|
||||
0b00 => Scalar::F32,
|
||||
0b01 => Scalar::I32,
|
||||
0b10 => Scalar::U32,
|
||||
_ => continue,
|
||||
};
|
||||
let (size, second_size) = match bits >> 2 {
|
||||
@ -937,12 +890,12 @@ fn inject_standard_builtins(
|
||||
|
||||
let args = vec![
|
||||
match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
match second_size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -969,25 +922,25 @@ fn inject_standard_builtins(
|
||||
0b10 => Some(VectorSize::Quad),
|
||||
_ => None,
|
||||
};
|
||||
let (kind, splatted, boolean) = match bits >> 2 {
|
||||
0b000 => (Sk::Sint, false, true),
|
||||
0b001 => (Sk::Uint, false, true),
|
||||
0b010 => (Sk::Float, false, true),
|
||||
0b011 => (Sk::Float, false, false),
|
||||
_ => (Sk::Float, true, false),
|
||||
let (scalar, splatted, boolean) = match bits >> 2 {
|
||||
0b000 => (Scalar::I32, false, true),
|
||||
0b001 => (Scalar::U32, false, true),
|
||||
0b010 => (Scalar::F32, false, true),
|
||||
0b011 => (Scalar::F32, false, false),
|
||||
_ => (Scalar::F32, true, false),
|
||||
};
|
||||
|
||||
let ty = |kind, width| match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(kind, width),
|
||||
ty(kind, width),
|
||||
ty(scalar),
|
||||
ty(scalar),
|
||||
match (boolean, splatted) {
|
||||
(true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
|
||||
(_, false) => TypeInner::Scalar { kind, width },
|
||||
_ => ty(kind, width),
|
||||
(true, _) => ty(Scalar::BOOL),
|
||||
(_, false) => TypeInner::Scalar(scalar),
|
||||
_ => ty(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1009,10 +962,10 @@ fn inject_standard_builtins(
|
||||
// 0b11010 is the last element since splatted single elements
|
||||
// were already added
|
||||
for bits in 0..0b11011 {
|
||||
let kind = match bits & 0b11 {
|
||||
0b00 => Sk::Float,
|
||||
0b01 => Sk::Sint,
|
||||
0b10 => Sk::Uint,
|
||||
let scalar = match bits & 0b11 {
|
||||
0b00 => Scalar::F32,
|
||||
0b01 => Scalar::I32,
|
||||
0b10 => Scalar::U32,
|
||||
_ => continue,
|
||||
};
|
||||
let size = match (bits >> 2) & 0b11 {
|
||||
@ -1024,11 +977,11 @@ fn inject_standard_builtins(
|
||||
let splatted = bits & 0b10000 == 0b10000;
|
||||
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let limit_ty = || match splatted {
|
||||
true => TypeInner::Scalar { kind, width },
|
||||
true => TypeInner::Scalar(scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
|
||||
@ -1049,7 +1002,6 @@ fn inject_standard_builtins(
|
||||
|
||||
/// Injects the builtins into declaration that need doubles
|
||||
fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Module, name: &str) {
|
||||
let width = 8;
|
||||
match name {
|
||||
"abs" | "sign" => {
|
||||
// bits layout
|
||||
@ -1061,11 +1013,11 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
}];
|
||||
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -1091,16 +1043,16 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b101 => (Some(VectorSize::Tri), Some(VectorSize::Tri)),
|
||||
_ => (Some(VectorSize::Quad), Some(VectorSize::Quad)),
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
|
||||
let args = vec![
|
||||
match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
match second_size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1127,24 +1079,24 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => None,
|
||||
};
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
let (splatted, boolean) = match bits >> 2 {
|
||||
0b00 => (false, false),
|
||||
0b01 => (false, true),
|
||||
_ => (true, false),
|
||||
};
|
||||
|
||||
let ty = |kind, width| match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(kind, width),
|
||||
ty(kind, width),
|
||||
ty(scalar),
|
||||
ty(scalar),
|
||||
match (boolean, splatted) {
|
||||
(true, _) => ty(Sk::Bool, crate::BOOL_WIDTH),
|
||||
(_, false) => TypeInner::Scalar { kind, width },
|
||||
_ => ty(kind, width),
|
||||
(true, _) => ty(Scalar::BOOL),
|
||||
(_, false) => TypeInner::Scalar(scalar),
|
||||
_ => ty(scalar),
|
||||
},
|
||||
];
|
||||
|
||||
@ -1165,7 +1117,7 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
// 0b110 is the last element since splatted with single elements
|
||||
// is equal to normal single elements
|
||||
for bits in 0..0b111 {
|
||||
let kind = Sk::Float;
|
||||
let scalar = Scalar::F64;
|
||||
let size = match bits & 0b11 {
|
||||
0b00 => Some(VectorSize::Bi),
|
||||
0b01 => Some(VectorSize::Tri),
|
||||
@ -1175,11 +1127,11 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
let splatted = bits & 0b100 == 0b100;
|
||||
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
let limit_ty = || match splatted {
|
||||
true => TypeInner::Scalar { kind, width },
|
||||
true => TypeInner::Scalar(scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
|
||||
@ -1192,14 +1144,15 @@ fn inject_double_builtin(declaration: &mut FunctionDeclaration, module: &mut Mod
|
||||
}
|
||||
"lessThan" | "greaterThan" | "lessThanEqual" | "greaterThanEqual" | "equal"
|
||||
| "notEqual" => {
|
||||
let scalar = Scalar::F64;
|
||||
for bits in 0..0b11 {
|
||||
let (size, kind) = match bits {
|
||||
0b00 => (VectorSize::Bi, Sk::Float),
|
||||
0b01 => (VectorSize::Tri, Sk::Float),
|
||||
_ => (VectorSize::Quad, Sk::Float),
|
||||
let size = match bits {
|
||||
0b00 => VectorSize::Bi,
|
||||
0b01 => VectorSize::Tri,
|
||||
_ => VectorSize::Quad,
|
||||
};
|
||||
|
||||
let ty = || TypeInner::Vector { size, kind, width };
|
||||
let ty = || TypeInner::Vector { size, scalar };
|
||||
let args = vec![ty(), ty()];
|
||||
|
||||
let fun = MacroCall::Binary(match name {
|
||||
@ -1227,6 +1180,10 @@ fn inject_common_builtin(
|
||||
name: &str,
|
||||
float_width: crate::Bytes,
|
||||
) {
|
||||
let float_scalar = Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
};
|
||||
match name {
|
||||
"ceil" | "round" | "roundEven" | "floor" | "fract" | "trunc" | "sqrt" | "inversesqrt"
|
||||
| "normalize" | "length" | "isinf" | "isnan" => {
|
||||
@ -1243,13 +1200,9 @@ fn inject_common_builtin(
|
||||
let args = vec![match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
}];
|
||||
|
||||
let fun = match name {
|
||||
@ -1280,16 +1233,9 @@ fn inject_common_builtin(
|
||||
0b10 => Some(VectorSize::Tri),
|
||||
_ => Some(VectorSize::Quad),
|
||||
};
|
||||
let ty = |kind| match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind,
|
||||
width: float_width,
|
||||
},
|
||||
let ty = |scalar| match size {
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
let fun = match name {
|
||||
@ -1300,15 +1246,18 @@ fn inject_common_builtin(
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let second_kind = if fun == MacroCall::MathFunction(MathFunction::Ldexp) {
|
||||
Sk::Sint
|
||||
let second_scalar = if fun == MacroCall::MathFunction(MathFunction::Ldexp) {
|
||||
Scalar {
|
||||
kind: Sk::Sint,
|
||||
width: float_width,
|
||||
}
|
||||
} else {
|
||||
Sk::Float
|
||||
float_scalar
|
||||
};
|
||||
|
||||
declaration
|
||||
.overloads
|
||||
.push(module.add_builtin(vec![ty(Sk::Float), ty(second_kind)], fun))
|
||||
.push(module.add_builtin(vec![ty(Scalar::F32), ty(second_scalar)], fun))
|
||||
}
|
||||
}
|
||||
"transpose" => {
|
||||
@ -1389,13 +1338,9 @@ fn inject_common_builtin(
|
||||
args.push(match maybe_size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
})
|
||||
}
|
||||
|
||||
@ -1414,13 +1359,11 @@ fn inject_common_builtin(
|
||||
let args = vec![
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
];
|
||||
|
||||
@ -1447,13 +1390,11 @@ fn inject_common_builtin(
|
||||
let args = vec![
|
||||
TypeInner::Vector {
|
||||
size: size1,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
TypeInner::Vector {
|
||||
size: size2,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
];
|
||||
|
||||
@ -1476,13 +1417,9 @@ fn inject_common_builtin(
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let args = vec![ty(), ty(), ty()];
|
||||
|
||||
@ -1509,22 +1446,11 @@ fn inject_common_builtin(
|
||||
let ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let args = vec![
|
||||
ty(),
|
||||
ty(),
|
||||
TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
},
|
||||
];
|
||||
let args = vec![ty(), ty(), TypeInner::Scalar(Scalar::F32)];
|
||||
declaration
|
||||
.overloads
|
||||
.push(module.add_builtin(args, MacroCall::MathFunction(MathFunction::Refract)))
|
||||
@ -1549,19 +1475,12 @@ fn inject_common_builtin(
|
||||
let base_ty = || match size {
|
||||
Some(size) => TypeInner::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
None => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
scalar: float_scalar,
|
||||
},
|
||||
None => TypeInner::Scalar(float_scalar),
|
||||
};
|
||||
let ty = || match splatted {
|
||||
true => TypeInner::Scalar {
|
||||
kind: Sk::Float,
|
||||
width: float_width,
|
||||
},
|
||||
true => TypeInner::Scalar(float_scalar),
|
||||
false => base_ty(),
|
||||
};
|
||||
declaration.overloads.push(module.add_builtin(
|
||||
@ -1810,8 +1729,7 @@ impl MacroCall {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: Scalar::U32,
|
||||
},
|
||||
},
|
||||
Span::default(),
|
||||
@ -2100,7 +2018,7 @@ fn texture_call(
|
||||
let mut array_index = comps.array_index;
|
||||
|
||||
if let Some(ref mut array_index_expr) = array_index {
|
||||
ctx.conversion(array_index_expr, meta, Sk::Sint, 4)?;
|
||||
ctx.conversion(array_index_expr, meta, Scalar::I32)?;
|
||||
}
|
||||
|
||||
Ok(ctx.add_expression(
|
||||
|
@ -9,8 +9,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
front::Typifier, proc::Emitter, AddressSpace, Arena, BinaryOperator, Block, Expression,
|
||||
FastHashMap, FunctionArgument, Handle, Literal, LocalVariable, RelationalFunction, ScalarKind,
|
||||
Span, Statement, Type, TypeInner, VectorSize,
|
||||
FastHashMap, FunctionArgument, Handle, Literal, LocalVariable, RelationalFunction, Scalar,
|
||||
ScalarKind, Span, Statement, Type, TypeInner, VectorSize,
|
||||
};
|
||||
use std::ops::Index;
|
||||
|
||||
@ -602,7 +602,7 @@ impl<'a> Context<'a> {
|
||||
|
||||
match op {
|
||||
BinaryOperator::ShiftLeft | BinaryOperator::ShiftRight => {
|
||||
self.implicit_conversion(&mut right, right_meta, ScalarKind::Uint, 4)?
|
||||
self.implicit_conversion(&mut right, right_meta, Scalar::U32)?
|
||||
}
|
||||
_ => self
|
||||
.binary_implicit_conversion(&mut left, left_meta, &mut right, right_meta)?,
|
||||
@ -824,9 +824,9 @@ impl<'a> Context<'a> {
|
||||
_ => self.add_expression(Expression::Binary { left, op, right }, meta)?,
|
||||
},
|
||||
(
|
||||
&TypeInner::Scalar {
|
||||
&TypeInner::Scalar(Scalar {
|
||||
width: left_width, ..
|
||||
},
|
||||
}),
|
||||
&TypeInner::Matrix {
|
||||
rows,
|
||||
columns,
|
||||
@ -911,9 +911,9 @@ impl<'a> Context<'a> {
|
||||
columns,
|
||||
width: left_width,
|
||||
},
|
||||
&TypeInner::Scalar {
|
||||
&TypeInner::Scalar(Scalar {
|
||||
width: right_width, ..
|
||||
},
|
||||
}),
|
||||
) => {
|
||||
// Check that the two arguments have the same width
|
||||
if left_width != right_width {
|
||||
@ -1100,37 +1100,24 @@ impl<'a> Context<'a> {
|
||||
|
||||
// We need to do some custom implicit conversions since the two target expressions
|
||||
// are in different bodies
|
||||
if let (
|
||||
Some((accept_power, accept_width, accept_kind)),
|
||||
Some((reject_power, reject_width, reject_kind)),
|
||||
) = (
|
||||
if let (Some((accept_power, accept_scalar)), Some((reject_power, reject_scalar))) = (
|
||||
// Get the components of both branches and calculate the type power
|
||||
self.expr_scalar_components(accept, accept_meta)?
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
self.expr_scalar_components(reject, reject_meta)?
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
) {
|
||||
match accept_power.cmp(&reject_power) {
|
||||
std::cmp::Ordering::Less => {
|
||||
accept_body = self.with_body(accept_body, |ctx| {
|
||||
ctx.conversion(
|
||||
&mut accept,
|
||||
accept_meta,
|
||||
reject_kind,
|
||||
reject_width,
|
||||
)?;
|
||||
ctx.conversion(&mut accept, accept_meta, reject_scalar)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
std::cmp::Ordering::Equal => {}
|
||||
std::cmp::Ordering::Greater => {
|
||||
reject_body = self.with_body(reject_body, |ctx| {
|
||||
ctx.conversion(
|
||||
&mut reject,
|
||||
reject_meta,
|
||||
accept_kind,
|
||||
accept_width,
|
||||
)?;
|
||||
ctx.conversion(&mut reject, reject_meta, accept_scalar)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
@ -1201,8 +1188,8 @@ impl<'a> Context<'a> {
|
||||
ref ty => ty,
|
||||
};
|
||||
|
||||
if let Some((kind, width)) = scalar_components(ty) {
|
||||
self.implicit_conversion(&mut value, value_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components(ty) {
|
||||
self.implicit_conversion(&mut value, value_meta, scalar)?;
|
||||
}
|
||||
|
||||
self.lower_store(pointer, value, meta)?;
|
||||
@ -1218,13 +1205,13 @@ impl<'a> Context<'a> {
|
||||
};
|
||||
|
||||
let res = match *self.resolve_type(left, meta)? {
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
let ty = TypeInner::Scalar { kind, width };
|
||||
Literal::one(kind, width).map(|i| (ty, i, None, None))
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let ty = TypeInner::Scalar(scalar);
|
||||
Literal::one(scalar).map(|i| (ty, i, None, None))
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
let ty = TypeInner::Vector { size, kind, width };
|
||||
Literal::one(kind, width).map(|i| (ty, i, Some(size), None))
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let ty = TypeInner::Vector { size, scalar };
|
||||
Literal::one(scalar).map(|i| (ty, i, Some(size), None))
|
||||
}
|
||||
TypeInner::Matrix {
|
||||
columns,
|
||||
@ -1236,8 +1223,11 @@ impl<'a> Context<'a> {
|
||||
rows,
|
||||
width,
|
||||
};
|
||||
Literal::one(ScalarKind::Float, width)
|
||||
.map(|i| (ty, i, Some(rows), Some(columns)))
|
||||
Literal::one(Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
})
|
||||
.map(|i| (ty, i, Some(rows), Some(columns)))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
@ -1323,19 +1313,14 @@ impl<'a> Context<'a> {
|
||||
Expression::Literal(Literal::U32(size.get())),
|
||||
meta,
|
||||
)?;
|
||||
self.forced_conversion(
|
||||
&mut array_length,
|
||||
meta,
|
||||
ScalarKind::Sint,
|
||||
4,
|
||||
)?;
|
||||
self.forced_conversion(&mut array_length, meta, Scalar::I32)?;
|
||||
array_length
|
||||
}
|
||||
// let the error be handled in type checking if it's not a dynamic array
|
||||
_ => {
|
||||
let mut array_length = self
|
||||
.add_expression(Expression::ArrayLength(lowered_array), meta)?;
|
||||
self.conversion(&mut array_length, meta, ScalarKind::Sint, 4)?;
|
||||
self.conversion(&mut array_length, meta, Scalar::I32)?;
|
||||
array_length
|
||||
}
|
||||
}
|
||||
@ -1376,7 +1361,7 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: Handle<Expression>,
|
||||
meta: Span,
|
||||
) -> Result<Option<(ScalarKind, crate::Bytes)>> {
|
||||
) -> Result<Option<Scalar>> {
|
||||
let ty = self.resolve_type(expr, meta)?;
|
||||
Ok(scalar_components(ty))
|
||||
}
|
||||
@ -1384,21 +1369,20 @@ impl<'a> Context<'a> {
|
||||
pub fn expr_power(&mut self, expr: Handle<Expression>, meta: Span) -> Result<Option<u32>> {
|
||||
Ok(self
|
||||
.expr_scalar_components(expr, meta)?
|
||||
.and_then(|(kind, width)| type_power(kind, width)))
|
||||
.and_then(type_power))
|
||||
}
|
||||
|
||||
pub fn conversion(
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
*expr = self.add_expression(
|
||||
Expression::As {
|
||||
expr: *expr,
|
||||
kind,
|
||||
convert: Some(width),
|
||||
kind: scalar.kind,
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?;
|
||||
@ -1410,14 +1394,13 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
if let (Some(tgt_power), Some(expr_power)) =
|
||||
(type_power(kind, width), self.expr_power(*expr, meta)?)
|
||||
(type_power(scalar), self.expr_power(*expr, meta)?)
|
||||
{
|
||||
if tgt_power > expr_power {
|
||||
self.conversion(expr, meta, kind, width)?;
|
||||
self.conversion(expr, meta, scalar)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1428,12 +1411,11 @@ impl<'a> Context<'a> {
|
||||
&mut self,
|
||||
expr: &mut Handle<Expression>,
|
||||
meta: Span,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
) -> Result<()> {
|
||||
if let Some((expr_scalar_kind, expr_width)) = self.expr_scalar_components(*expr, meta)? {
|
||||
if expr_scalar_kind != kind || expr_width != width {
|
||||
self.conversion(expr, meta, kind, width)?;
|
||||
if let Some(expr_scalar) = self.expr_scalar_components(*expr, meta)? {
|
||||
if expr_scalar != scalar {
|
||||
self.conversion(expr, meta, scalar)?;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1450,21 +1432,17 @@ impl<'a> Context<'a> {
|
||||
let left_components = self.expr_scalar_components(*left, left_meta)?;
|
||||
let right_components = self.expr_scalar_components(*right, right_meta)?;
|
||||
|
||||
if let (
|
||||
Some((left_power, left_width, left_kind)),
|
||||
Some((right_power, right_width, right_kind)),
|
||||
) = (
|
||||
left_components.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
right_components
|
||||
.and_then(|(kind, width)| Some((type_power(kind, width)?, width, kind))),
|
||||
if let (Some((left_power, left_scalar)), Some((right_power, right_scalar))) = (
|
||||
left_components.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
right_components.and_then(|scalar| Some((type_power(scalar)?, scalar))),
|
||||
) {
|
||||
match left_power.cmp(&right_power) {
|
||||
std::cmp::Ordering::Less => {
|
||||
self.conversion(left, left_meta, right_kind, right_width)?;
|
||||
self.conversion(left, left_meta, right_scalar)?;
|
||||
}
|
||||
std::cmp::Ordering::Equal => {}
|
||||
std::cmp::Ordering::Greater => {
|
||||
self.conversion(right, right_meta, left_kind, left_width)?;
|
||||
self.conversion(right, right_meta, left_scalar)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
front::glsl::types::type_power, proc::ensure_block_returns, AddressSpace, Block, EntryPoint,
|
||||
Expression, Function, FunctionArgument, FunctionResult, Handle, Literal, LocalVariable,
|
||||
Expression, Function, FunctionArgument, FunctionResult, Handle, Literal, LocalVariable, Scalar,
|
||||
ScalarKind, Span, Statement, StructMember, Type, TypeInner,
|
||||
};
|
||||
use std::iter;
|
||||
@ -20,7 +20,7 @@ struct ProxyWrite {
|
||||
/// A pointer to read the value of the store
|
||||
value: Handle<Expression>,
|
||||
/// An optional conversion to be applied
|
||||
convert: Option<(ScalarKind, crate::Bytes)>,
|
||||
convert: Option<Scalar>,
|
||||
}
|
||||
|
||||
impl Frontend {
|
||||
@ -68,10 +68,14 @@ impl Frontend {
|
||||
let expr_is_bool = expr_type.scalar_kind() == Some(ScalarKind::Bool);
|
||||
|
||||
// Special case: if casting from a bool, we need to use Select and not As.
|
||||
match ctx.module.types[ty].inner.scalar_kind() {
|
||||
Some(result_scalar_kind) if expr_is_bool && result_scalar_kind != ScalarKind::Bool => {
|
||||
let l0 = Literal::zero(result_scalar_kind, 4).unwrap();
|
||||
let l1 = Literal::one(result_scalar_kind, 4).unwrap();
|
||||
match ctx.module.types[ty].inner.scalar() {
|
||||
Some(result_scalar) if expr_is_bool && result_scalar.kind != ScalarKind::Bool => {
|
||||
let result_scalar = Scalar {
|
||||
width: 4,
|
||||
..result_scalar
|
||||
};
|
||||
let l0 = Literal::zero(result_scalar).unwrap();
|
||||
let l1 = Literal::one(result_scalar).unwrap();
|
||||
let mut reject = ctx.add_expression(Expression::Literal(l0), expr_meta)?;
|
||||
let mut accept = ctx.add_expression(Expression::Literal(l1), expr_meta)?;
|
||||
|
||||
@ -93,24 +97,16 @@ impl Frontend {
|
||||
}
|
||||
|
||||
Ok(match ctx.module.types[ty].inner {
|
||||
TypeInner::Vector { size, kind, width } if vector_size.is_none() => {
|
||||
ctx.forced_conversion(&mut value, expr_meta, kind, width)?;
|
||||
TypeInner::Vector { size, scalar } if vector_size.is_none() => {
|
||||
ctx.forced_conversion(&mut value, expr_meta, scalar)?;
|
||||
|
||||
if let TypeInner::Scalar { .. } = *ctx.resolve_type(value, expr_meta)? {
|
||||
ctx.add_expression(Expression::Splat { size, value }, meta)?
|
||||
} else {
|
||||
self.vector_constructor(
|
||||
ctx,
|
||||
ty,
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
&[(value, expr_meta)],
|
||||
meta,
|
||||
)?
|
||||
self.vector_constructor(ctx, ty, size, scalar, &[(value, expr_meta)], meta)?
|
||||
}
|
||||
}
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let mut expr = value;
|
||||
if let TypeInner::Vector { .. } | TypeInner::Matrix { .. } =
|
||||
*ctx.resolve_type(value, expr_meta)?
|
||||
@ -136,23 +132,23 @@ impl Frontend {
|
||||
|
||||
ctx.add_expression(
|
||||
Expression::As {
|
||||
kind,
|
||||
kind: scalar.kind,
|
||||
expr,
|
||||
convert: Some(width),
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
if vector_size.map_or(true, |s| s != size) {
|
||||
value = ctx.vector_resize(size, value, expr_meta)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
Expression::As {
|
||||
kind,
|
||||
kind: scalar.kind,
|
||||
expr: value,
|
||||
convert: Some(width),
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
meta,
|
||||
)?
|
||||
@ -166,8 +162,8 @@ impl Frontend {
|
||||
let scalar_components = members
|
||||
.get(0)
|
||||
.and_then(|member| scalar_components(&ctx.module.types[member.ty].inner));
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
@ -181,8 +177,8 @@ impl Frontend {
|
||||
|
||||
TypeInner::Array { base, .. } => {
|
||||
let scalar_components = scalar_components(&ctx.module.types[base].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut value, expr_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.add_expression(
|
||||
@ -220,9 +216,13 @@ impl Frontend {
|
||||
// `Expression::As` doesn't support matrix width
|
||||
// casts so we need to do some extra work for casts
|
||||
|
||||
ctx.forced_conversion(&mut value, expr_meta, ScalarKind::Float, width)?;
|
||||
let element_scalar = Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
};
|
||||
ctx.forced_conversion(&mut value, expr_meta, element_scalar)?;
|
||||
match *ctx.resolve_type(value, expr_meta)? {
|
||||
TypeInner::Scalar { .. } => {
|
||||
TypeInner::Scalar(_) => {
|
||||
// If a matrix is constructed with a single scalar value, then that
|
||||
// value is used to initialize all the values along the diagonal of
|
||||
// the matrix; the rest are given zeros.
|
||||
@ -231,14 +231,13 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
);
|
||||
|
||||
let zero_literal = Literal::zero(ScalarKind::Float, width).unwrap();
|
||||
let zero_literal = Literal::zero(element_scalar).unwrap();
|
||||
let zero = ctx.add_expression(Expression::Literal(zero_literal), meta)?;
|
||||
|
||||
for i in 0..columns as u32 {
|
||||
@ -268,8 +267,8 @@ impl Frontend {
|
||||
// (column i, row j) in the argument will be initialized from there. All
|
||||
// other components will be initialized to the identity matrix.
|
||||
|
||||
let zero_literal = Literal::zero(ScalarKind::Float, width).unwrap();
|
||||
let one_literal = Literal::one(ScalarKind::Float, width).unwrap();
|
||||
let zero_literal = Literal::zero(element_scalar).unwrap();
|
||||
let one_literal = Literal::one(element_scalar).unwrap();
|
||||
|
||||
let zero = ctx.add_expression(Expression::Literal(zero_literal), meta)?;
|
||||
let one = ctx.add_expression(Expression::Literal(one_literal), meta)?;
|
||||
@ -279,8 +278,7 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
@ -360,15 +358,14 @@ impl Frontend {
|
||||
ctx: &mut Context,
|
||||
ty: Handle<Type>,
|
||||
size: crate::VectorSize,
|
||||
kind: ScalarKind,
|
||||
width: crate::Bytes,
|
||||
scalar: Scalar,
|
||||
args: &[(Handle<Expression>, Span)],
|
||||
meta: Span,
|
||||
) -> Result<Handle<Expression>> {
|
||||
let mut components = Vec::with_capacity(size as usize);
|
||||
|
||||
for (mut arg, expr_meta) in args.iter().copied() {
|
||||
ctx.forced_conversion(&mut arg, expr_meta, kind, width)?;
|
||||
ctx.forced_conversion(&mut arg, expr_meta, scalar)?;
|
||||
|
||||
if components.len() >= size as usize {
|
||||
break;
|
||||
@ -429,8 +426,12 @@ impl Frontend {
|
||||
} => {
|
||||
let mut flattened = Vec::with_capacity(columns as usize * rows as usize);
|
||||
|
||||
let element_scalar = Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
};
|
||||
for (mut arg, meta) in args.iter().copied() {
|
||||
ctx.forced_conversion(&mut arg, meta, ScalarKind::Float, width)?;
|
||||
ctx.forced_conversion(&mut arg, meta, element_scalar)?;
|
||||
|
||||
match *ctx.resolve_type(arg, meta)? {
|
||||
TypeInner::Vector { size, .. } => {
|
||||
@ -453,8 +454,7 @@ impl Frontend {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: element_scalar,
|
||||
},
|
||||
},
|
||||
meta,
|
||||
@ -471,14 +471,14 @@ impl Frontend {
|
||||
}
|
||||
None
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
return self.vector_constructor(ctx, ty, size, kind, width, &args, meta)
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
return self.vector_constructor(ctx, ty, size, scalar, &args, meta)
|
||||
}
|
||||
TypeInner::Array { base, .. } => {
|
||||
for (mut arg, meta) in args.iter().copied() {
|
||||
let scalar_components = scalar_components(&ctx.module.types[base].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, scalar)?;
|
||||
}
|
||||
|
||||
components.push(arg)
|
||||
@ -503,8 +503,8 @@ impl Frontend {
|
||||
for ((mut arg, meta), scalar_components) in
|
||||
args.iter().copied().zip(struct_member_data.iter().copied())
|
||||
{
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut arg, meta, scalar)?;
|
||||
}
|
||||
|
||||
components.push(arg)
|
||||
@ -813,8 +813,8 @@ impl Frontend {
|
||||
let scalar_comps = scalar_components(&ctx.module.types[*parameter].inner);
|
||||
|
||||
// Apply implicit conversions as needed
|
||||
if let Some((kind, width)) = scalar_comps {
|
||||
ctx.implicit_conversion(&mut handle, meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_comps {
|
||||
ctx.implicit_conversion(&mut handle, meta, scalar)?;
|
||||
}
|
||||
|
||||
arguments.push(handle)
|
||||
@ -850,8 +850,8 @@ impl Frontend {
|
||||
meta,
|
||||
)?;
|
||||
|
||||
if let Some((kind, width)) = proxy_write.convert {
|
||||
ctx.conversion(&mut value, meta, kind, width)?;
|
||||
if let Some(scalar) = proxy_write.convert {
|
||||
ctx.conversion(&mut value, meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.emit_restart();
|
||||
@ -893,10 +893,10 @@ impl Frontend {
|
||||
// If the argument is to be passed as a pointer but the type of the
|
||||
// expression returns a vector it must mean that it was for example
|
||||
// swizzled and it must be spilled into a local before calling
|
||||
TypeInner::Vector { size, kind, width } => Some(ctx.module.types.insert(
|
||||
TypeInner::Vector { size, scalar } => Some(ctx.module.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
},
|
||||
Span::default(),
|
||||
)),
|
||||
@ -906,13 +906,12 @@ impl Frontend {
|
||||
TypeInner::Pointer { base, space } if space != AddressSpace::Function => Some(base),
|
||||
TypeInner::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} if space != AddressSpace::Function => {
|
||||
let inner = match size {
|
||||
Some(size) => TypeInner::Vector { size, kind, width },
|
||||
None => TypeInner::Scalar { kind, width },
|
||||
Some(size) => TypeInner::Vector { size, scalar },
|
||||
None => TypeInner::Scalar(scalar),
|
||||
};
|
||||
|
||||
Some(
|
||||
@ -1512,31 +1511,22 @@ fn conversion(target: &TypeInner, source: &TypeInner) -> Option<Conversion> {
|
||||
use ScalarKind::*;
|
||||
|
||||
// Gather the `ScalarKind` and scalar width from both the target and the source
|
||||
let (target_kind, target_width, source_kind, source_width) = match (target, source) {
|
||||
let (target_scalar, source_scalar) = match (target, source) {
|
||||
// Conversions between scalars are allowed
|
||||
(
|
||||
&TypeInner::Scalar {
|
||||
kind: tgt_kind,
|
||||
width: tgt_width,
|
||||
},
|
||||
&TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
},
|
||||
) => (tgt_kind, tgt_width, src_kind, src_width),
|
||||
(&TypeInner::Scalar(tgt_scalar), &TypeInner::Scalar(src_scalar)) => {
|
||||
(tgt_scalar, src_scalar)
|
||||
}
|
||||
// Conversions between vectors of the same size are allowed
|
||||
(
|
||||
&TypeInner::Vector {
|
||||
kind: tgt_kind,
|
||||
size: tgt_size,
|
||||
width: tgt_width,
|
||||
scalar: tgt_scalar,
|
||||
},
|
||||
&TypeInner::Vector {
|
||||
kind: src_kind,
|
||||
size: src_size,
|
||||
width: src_width,
|
||||
scalar: src_scalar,
|
||||
},
|
||||
) if tgt_size == src_size => (tgt_kind, tgt_width, src_kind, src_width),
|
||||
) if tgt_size == src_size => (tgt_scalar, src_scalar),
|
||||
// Conversions between matrices of the same size are allowed
|
||||
(
|
||||
&TypeInner::Matrix {
|
||||
@ -1549,29 +1539,63 @@ fn conversion(target: &TypeInner, source: &TypeInner) -> Option<Conversion> {
|
||||
columns: src_cols,
|
||||
width: src_width,
|
||||
},
|
||||
) if tgt_cols == src_cols && tgt_rows == src_rows => (Float, tgt_width, Float, src_width),
|
||||
) if tgt_cols == src_cols && tgt_rows == src_rows => (
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: tgt_width,
|
||||
},
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: src_width,
|
||||
},
|
||||
),
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
// Check if source can be converted into target, if this is the case then the type
|
||||
// power of target must be higher than that of source
|
||||
let target_power = type_power(target_kind, target_width);
|
||||
let source_power = type_power(source_kind, source_width);
|
||||
let target_power = type_power(target_scalar);
|
||||
let source_power = type_power(source_scalar);
|
||||
if target_power < source_power {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(
|
||||
match ((target_kind, target_width), (source_kind, source_width)) {
|
||||
// A conversion from a float to a double is special
|
||||
((Float, 8), (Float, 4)) => Conversion::FloatToDouble,
|
||||
// A conversion from an integer to a float is special
|
||||
((Float, 4), (Sint | Uint, _)) => Conversion::IntToFloat,
|
||||
// A conversion from an integer to a double is special
|
||||
((Float, 8), (Sint | Uint, _)) => Conversion::IntToDouble,
|
||||
_ => Conversion::Other,
|
||||
},
|
||||
)
|
||||
Some(match (target_scalar, source_scalar) {
|
||||
// A conversion from a float to a double is special
|
||||
(
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: 8,
|
||||
},
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: 4,
|
||||
},
|
||||
) => Conversion::FloatToDouble,
|
||||
// A conversion from an integer to a float is special
|
||||
(
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: 4,
|
||||
},
|
||||
Scalar {
|
||||
kind: Sint | Uint,
|
||||
width: _,
|
||||
},
|
||||
) => Conversion::IntToFloat,
|
||||
// A conversion from an integer to a double is special
|
||||
(
|
||||
Scalar {
|
||||
kind: Float,
|
||||
width: 8,
|
||||
},
|
||||
Scalar {
|
||||
kind: Sint | Uint,
|
||||
width: _,
|
||||
},
|
||||
) => Conversion::IntToDouble,
|
||||
_ => Conversion::Other,
|
||||
})
|
||||
}
|
||||
|
||||
/// Helper method returning all the non standard builtin variations needed
|
||||
@ -1581,10 +1605,10 @@ fn builtin_required_variations<'a>(args: impl Iterator<Item = &'a TypeInner>) ->
|
||||
|
||||
for ty in args {
|
||||
match *ty {
|
||||
TypeInner::ValuePointer { kind, width, .. }
|
||||
| TypeInner::Scalar { kind, width }
|
||||
| TypeInner::Vector { kind, width, .. } => {
|
||||
if kind == ScalarKind::Float && width == 8 {
|
||||
TypeInner::ValuePointer { scalar, .. }
|
||||
| TypeInner::Scalar(scalar)
|
||||
| TypeInner::Vector { scalar, .. } => {
|
||||
if scalar.kind == ScalarKind::Float && scalar.width == 8 {
|
||||
variations |= BuiltinVariations::DOUBLE
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ use super::{
|
||||
error::{Error, ErrorKind},
|
||||
Span,
|
||||
};
|
||||
use crate::{proc::Alignment, Handle, Type, TypeInner, UniqueArena};
|
||||
use crate::{proc::Alignment, Handle, Scalar, Type, TypeInner, UniqueArena};
|
||||
|
||||
/// Struct with information needed for defining a struct member.
|
||||
///
|
||||
@ -53,12 +53,15 @@ pub fn calculate_offset(
|
||||
let (align, span) = match types[ty].inner {
|
||||
// 1. If the member is a scalar consuming N basic machine units,
|
||||
// the base alignment is N.
|
||||
TypeInner::Scalar { width, .. } => (Alignment::from_width(width), width as u32),
|
||||
TypeInner::Scalar(Scalar { width, .. }) => (Alignment::from_width(width), width as u32),
|
||||
// 2. If the member is a two- or four-component vector with components
|
||||
// consuming N basic machine units, the base alignment is 2N or 4N, respectively.
|
||||
// 3. If the member is a three-component vector with components consuming N
|
||||
// basic machine units, the base alignment is 4N.
|
||||
TypeInner::Vector { size, width, .. } => (
|
||||
TypeInner::Vector {
|
||||
size,
|
||||
scalar: Scalar { width, .. },
|
||||
} => (
|
||||
Alignment::from(size) * Alignment::from_width(width),
|
||||
size as u32 * width as u32,
|
||||
),
|
||||
|
@ -13,8 +13,8 @@ use crate::{
|
||||
Error, ErrorKind, Frontend, Span,
|
||||
},
|
||||
proc::Alignment,
|
||||
AddressSpace, Expression, FunctionResult, Handle, ScalarKind, Statement, StructMember, Type,
|
||||
TypeInner,
|
||||
AddressSpace, Expression, FunctionResult, Handle, Scalar, ScalarKind, Statement, StructMember,
|
||||
Type, TypeInner,
|
||||
};
|
||||
|
||||
use super::{DeclarationContext, ParsingContext, Result};
|
||||
@ -34,10 +34,10 @@ fn element_or_member_type(
|
||||
) -> Handle<Type> {
|
||||
match types[ty].inner {
|
||||
// The child type of a vector is a scalar of the same kind and width
|
||||
TypeInner::Vector { kind, width, .. } => types.insert(
|
||||
TypeInner::Vector { scalar, .. } => types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar { kind, width },
|
||||
inner: TypeInner::Scalar(scalar),
|
||||
},
|
||||
Default::default(),
|
||||
),
|
||||
@ -48,8 +48,10 @@ fn element_or_member_type(
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -156,8 +158,8 @@ impl<'source> ParsingContext<'source> {
|
||||
let (mut init, init_meta) = ctx.lower_expect(stmt, frontend, expr, ExprPos::Rhs)?;
|
||||
|
||||
let scalar_components = scalar_components(&ctx.module.types[ty].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.implicit_conversion(&mut init, init_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.implicit_conversion(&mut init, init_meta, scalar)?;
|
||||
}
|
||||
|
||||
Ok((init, init_meta))
|
||||
@ -233,9 +235,8 @@ impl<'source> ParsingContext<'source> {
|
||||
let (mut expr, init_meta) = self.parse_initializer(frontend, ty, ctx.ctx)?;
|
||||
|
||||
let scalar_components = scalar_components(&ctx.ctx.module.types[ty].inner);
|
||||
if let Some((kind, width)) = scalar_components {
|
||||
ctx.ctx
|
||||
.implicit_conversion(&mut expr, init_meta, kind, width)?;
|
||||
if let Some(scalar) = scalar_components {
|
||||
ctx.ctx.implicit_conversion(&mut expr, init_meta, scalar)?;
|
||||
}
|
||||
|
||||
ctx.ctx.is_const = prev_const;
|
||||
@ -509,10 +510,10 @@ impl<'source> ParsingContext<'source> {
|
||||
let (ty, meta) = self.parse_type_non_void(frontend, ctx)?;
|
||||
|
||||
match ctx.module.types[ty].inner {
|
||||
TypeInner::Scalar {
|
||||
TypeInner::Scalar(Scalar {
|
||||
kind: ScalarKind::Float | ScalarKind::Sint,
|
||||
..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => frontend.errors.push(Error {
|
||||
kind: ErrorKind::SemanticError(
|
||||
"Precision statement can only work on floats and ints".into(),
|
||||
|
@ -509,7 +509,7 @@ fn functions() {
|
||||
|
||||
#[test]
|
||||
fn constants() {
|
||||
use crate::{Constant, Expression, ScalarKind, Type, TypeInner};
|
||||
use crate::{Constant, Expression, Type, TypeInner};
|
||||
|
||||
let mut frontend = Frontend::default();
|
||||
|
||||
@ -536,10 +536,7 @@ fn constants() {
|
||||
ty,
|
||||
&Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4
|
||||
}
|
||||
inner: TypeInner::Scalar(crate::Scalar::F32)
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use super::{context::Context, Error, ErrorKind, Result, Span};
|
||||
use crate::{
|
||||
proc::ResolveContext, Bytes, Expression, Handle, ImageClass, ImageDimension, ScalarKind, Type,
|
||||
proc::ResolveContext, Expression, Handle, ImageClass, ImageDimension, Scalar, ScalarKind, Type,
|
||||
TypeInner, VectorSize,
|
||||
};
|
||||
|
||||
@ -8,38 +8,23 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
match type_name {
|
||||
"bool" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::BOOL),
|
||||
}),
|
||||
"float" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
}),
|
||||
"double" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 8,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F64),
|
||||
}),
|
||||
"int" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::I32),
|
||||
}),
|
||||
"uint" => Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::U32),
|
||||
}),
|
||||
"sampler" | "samplerShadow" => Some(Type {
|
||||
name: None,
|
||||
@ -48,13 +33,13 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
},
|
||||
}),
|
||||
word => {
|
||||
fn kind_width_parse(ty: &str) -> Option<(ScalarKind, u8)> {
|
||||
fn kind_width_parse(ty: &str) -> Option<Scalar> {
|
||||
Some(match ty {
|
||||
"" => (ScalarKind::Float, 4),
|
||||
"b" => (ScalarKind::Bool, crate::BOOL_WIDTH),
|
||||
"i" => (ScalarKind::Sint, 4),
|
||||
"u" => (ScalarKind::Uint, 4),
|
||||
"d" => (ScalarKind::Float, 8),
|
||||
"" => Scalar::F32,
|
||||
"b" => Scalar::BOOL,
|
||||
"i" => Scalar::I32,
|
||||
"u" => Scalar::U32,
|
||||
"d" => Scalar::F64,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -73,12 +58,12 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
|
||||
let kind = iter.next()?;
|
||||
let size = iter.next()?;
|
||||
let (kind, width) = kind_width_parse(kind)?;
|
||||
let scalar = kind_width_parse(kind)?;
|
||||
let size = size_parse(size)?;
|
||||
|
||||
Some(Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
})
|
||||
};
|
||||
|
||||
@ -87,7 +72,7 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
|
||||
let kind = iter.next()?;
|
||||
let size = iter.next()?;
|
||||
let (_, width) = kind_width_parse(kind)?;
|
||||
let Scalar { width, .. } = kind_width_parse(kind)?;
|
||||
|
||||
let (columns, rows) = if let Some(size) = size_parse(size) {
|
||||
(size, size)
|
||||
@ -204,21 +189,24 @@ pub fn parse_type(type_name: &str) -> Option<Type> {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn scalar_components(ty: &TypeInner) -> Option<(ScalarKind, Bytes)> {
|
||||
pub const fn scalar_components(ty: &TypeInner) -> Option<Scalar> {
|
||||
match *ty {
|
||||
TypeInner::Scalar { kind, width } => Some((kind, width)),
|
||||
TypeInner::Vector { kind, width, .. } => Some((kind, width)),
|
||||
TypeInner::Matrix { width, .. } => Some((ScalarKind::Float, width)),
|
||||
TypeInner::ValuePointer { kind, width, .. } => Some((kind, width)),
|
||||
TypeInner::Scalar(scalar)
|
||||
| TypeInner::Vector { scalar, .. }
|
||||
| TypeInner::ValuePointer { scalar, .. } => Some(scalar),
|
||||
TypeInner::Matrix { width, .. } => Some(Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn type_power(kind: ScalarKind, width: Bytes) -> Option<u32> {
|
||||
Some(match kind {
|
||||
pub const fn type_power(scalar: Scalar) -> Option<u32> {
|
||||
Some(match scalar.kind {
|
||||
ScalarKind::Sint => 0,
|
||||
ScalarKind::Uint => 1,
|
||||
ScalarKind::Float if width == 4 => 2,
|
||||
ScalarKind::Float if scalar.width == 4 => 2,
|
||||
ScalarKind::Float => 3,
|
||||
ScalarKind::Bool => return None,
|
||||
})
|
||||
|
@ -6,8 +6,8 @@ use super::{
|
||||
};
|
||||
use crate::{
|
||||
AddressSpace, Binding, BuiltIn, Constant, Expression, GlobalVariable, Handle, Interpolation,
|
||||
LocalVariable, ResourceBinding, ScalarKind, ShaderStage, SwizzleComponent, Type, TypeInner,
|
||||
VectorSize,
|
||||
LocalVariable, ResourceBinding, Scalar, ScalarKind, ShaderStage, SwizzleComponent, Type,
|
||||
TypeInner, VectorSize,
|
||||
};
|
||||
|
||||
pub struct VarDeclaration<'a, 'key> {
|
||||
@ -109,8 +109,7 @@ impl Frontend {
|
||||
"gl_Position" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::Position { invariant: false },
|
||||
mutable: true,
|
||||
@ -119,8 +118,7 @@ impl Frontend {
|
||||
"gl_FragCoord" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Quad,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::Position { invariant: false },
|
||||
mutable: false,
|
||||
@ -129,8 +127,7 @@ impl Frontend {
|
||||
"gl_PointCoord" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
builtin: BuiltIn::PointCoord,
|
||||
mutable: false,
|
||||
@ -143,8 +140,7 @@ impl Frontend {
|
||||
| "gl_LocalInvocationID" => BuiltInData {
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: Scalar::U32,
|
||||
},
|
||||
builtin: match name {
|
||||
"gl_GlobalInvocationID" => BuiltIn::GlobalInvocationId,
|
||||
@ -158,19 +154,13 @@ impl Frontend {
|
||||
storage: StorageQualifier::Input,
|
||||
},
|
||||
"gl_FrontFacing" => BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::BOOL),
|
||||
builtin: BuiltIn::FrontFacing,
|
||||
mutable: false,
|
||||
storage: StorageQualifier::Input,
|
||||
},
|
||||
"gl_PointSize" | "gl_FragDepth" => BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
builtin: match name {
|
||||
"gl_PointSize" => BuiltIn::PointSize,
|
||||
"gl_FragDepth" => BuiltIn::FragDepth,
|
||||
@ -183,10 +173,7 @@ impl Frontend {
|
||||
let base = ctx.module.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::F32),
|
||||
},
|
||||
meta,
|
||||
);
|
||||
@ -219,10 +206,7 @@ impl Frontend {
|
||||
};
|
||||
|
||||
BuiltInData {
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(Scalar::U32),
|
||||
builtin,
|
||||
mutable: false,
|
||||
storage: StorageQualifier::Input,
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::arena::{Handle, UniqueArena};
|
||||
use crate::{
|
||||
arena::{Handle, UniqueArena},
|
||||
Scalar,
|
||||
};
|
||||
|
||||
use super::{Error, LookupExpression, LookupHelper as _};
|
||||
|
||||
@ -61,8 +64,11 @@ fn extract_image_coordinates(
|
||||
ctx: &mut super::BlockContext,
|
||||
) -> (Handle<crate::Expression>, Option<Handle<crate::Expression>>) {
|
||||
let (given_size, kind) = match ctx.type_arena[coordinate_ty].inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => (None, kind),
|
||||
crate::TypeInner::Vector { size, kind, .. } => (Some(size), kind),
|
||||
crate::TypeInner::Scalar(Scalar { kind, .. }) => (None, kind),
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: Scalar { kind, .. },
|
||||
} => (Some(size), kind),
|
||||
ref other => unreachable!("Unexpected texture coordinate {:?}", other),
|
||||
};
|
||||
|
||||
@ -73,8 +79,7 @@ fn extract_image_coordinates(
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: Scalar { kind, width: 4 },
|
||||
},
|
||||
})
|
||||
.expect("Required coordinate type should have been set up by `parse_type_image`!")
|
||||
|
@ -2829,22 +2829,22 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
|
||||
let value_lexp = self.lookup_expression.lookup(value_id)?;
|
||||
let ty_lookup = self.lookup_type.lookup(result_type_id)?;
|
||||
let (kind, width) = match ctx.type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, width }
|
||||
| crate::TypeInner::Vector { kind, width, .. } => (kind, width),
|
||||
crate::TypeInner::Matrix { width, .. } => (crate::ScalarKind::Float, width),
|
||||
let scalar = match ctx.type_arena[ty_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar(scalar)
|
||||
| crate::TypeInner::Vector { scalar, .. } => scalar,
|
||||
crate::TypeInner::Matrix { width, .. } => crate::Scalar::float(width),
|
||||
_ => return Err(Error::InvalidAsType(ty_lookup.handle)),
|
||||
};
|
||||
|
||||
let expr = crate::Expression::As {
|
||||
expr: get_expr_handle!(value_id, value_lexp),
|
||||
kind,
|
||||
convert: if kind == crate::ScalarKind::Bool {
|
||||
kind: scalar.kind,
|
||||
convert: if scalar.kind == crate::ScalarKind::Bool {
|
||||
Some(crate::BOOL_WIDTH)
|
||||
} else if inst.op == Op::Bitcast {
|
||||
None
|
||||
} else {
|
||||
Some(width)
|
||||
Some(scalar.width)
|
||||
},
|
||||
};
|
||||
self.lookup_expression.insert(
|
||||
@ -3356,10 +3356,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let selector_lty = self.lookup_type.lookup(selector_lexp.type_id)?;
|
||||
let selector_handle = get_expr_handle!(selector, selector_lexp);
|
||||
let selector = match ctx.type_arena[selector_lty.handle].inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => {
|
||||
}) => {
|
||||
// IR expects a signed integer, so do a bitcast
|
||||
ctx.expressions.append(
|
||||
crate::Expression::As {
|
||||
@ -3370,10 +3370,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
span,
|
||||
)
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: _,
|
||||
} => selector_handle,
|
||||
}) => selector_handle,
|
||||
ref other => unimplemented!("Unexpected selector {:?}", other),
|
||||
};
|
||||
|
||||
@ -4244,10 +4244,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
self.switch(ModuleState::Type, inst.op)?;
|
||||
inst.expect(2)?;
|
||||
let id = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
};
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar::BOOL);
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4275,14 +4272,14 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let id = self.next()?;
|
||||
let width = self.next()?;
|
||||
let sign = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: match sign {
|
||||
0 => crate::ScalarKind::Uint,
|
||||
1 => crate::ScalarKind::Sint,
|
||||
_ => return Err(Error::InvalidSign(sign)),
|
||||
},
|
||||
width: map_width(width)?,
|
||||
};
|
||||
});
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4309,10 +4306,7 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
inst.expect(3)?;
|
||||
let id = self.next()?;
|
||||
let width = self.next()?;
|
||||
let inner = crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: map_width(width)?,
|
||||
};
|
||||
let inner = crate::TypeInner::Scalar(crate::Scalar::float(map_width(width)?));
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
@ -4340,15 +4334,14 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let id = self.next()?;
|
||||
let type_id = self.next()?;
|
||||
let type_lookup = self.lookup_type.lookup(type_id)?;
|
||||
let (kind, width) = match module.types[type_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, width),
|
||||
let scalar = match module.types[type_lookup.handle].inner {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::InvalidInnerType(type_id)),
|
||||
};
|
||||
let component_count = self.next()?;
|
||||
let inner = crate::TypeInner::Vector {
|
||||
size: map_vector_size(component_count)?,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
};
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
@ -4381,10 +4374,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
|
||||
let vector_type_lookup = self.lookup_type.lookup(vector_type_id)?;
|
||||
let inner = match module.types[vector_type_lookup.handle].inner {
|
||||
crate::TypeInner::Vector { size, width, .. } => crate::TypeInner::Matrix {
|
||||
crate::TypeInner::Vector { size, scalar } => crate::TypeInner::Matrix {
|
||||
columns: map_vector_size(num_columns)?,
|
||||
rows: size,
|
||||
width,
|
||||
width: scalar.width,
|
||||
},
|
||||
_ => return Err(Error::InvalidInnerType(vector_type_id)),
|
||||
};
|
||||
@ -4761,11 +4754,10 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: {
|
||||
let kind = crate::ScalarKind::Float;
|
||||
let width = 4;
|
||||
let scalar = crate::Scalar::F32;
|
||||
match dim.required_coordinate_size() {
|
||||
None => crate::TypeInner::Scalar { kind, width },
|
||||
Some(size) => crate::TypeInner::Vector { size, kind, width },
|
||||
None => crate::TypeInner::Scalar(scalar),
|
||||
Some(size) => crate::TypeInner::Vector { size, scalar },
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -4870,30 +4862,30 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
let ty = type_lookup.handle;
|
||||
|
||||
let literal = match module.types[ty].inner {
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::U32(low),
|
||||
_ => return Err(Error::InvalidTypeWidth(width as u32)),
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::I32(low as i32),
|
||||
_ => return Err(Error::InvalidTypeWidth(width as u32)),
|
||||
}
|
||||
}
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
} => {
|
||||
}) => {
|
||||
let low = self.next()?;
|
||||
match width {
|
||||
4 => crate::Literal::F32(f32::from_bits(low)),
|
||||
@ -5167,17 +5159,15 @@ impl<I: Iterator<Item = u32>> Frontend<I> {
|
||||
| crate::BuiltIn::SampleIndex
|
||||
| crate::BuiltIn::VertexIndex
|
||||
| crate::BuiltIn::PrimitiveIndex
|
||||
| crate::BuiltIn::LocalInvocationIndex => Some(crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
}),
|
||||
| crate::BuiltIn::LocalInvocationIndex => {
|
||||
Some(crate::TypeInner::Scalar(crate::Scalar::U32))
|
||||
}
|
||||
crate::BuiltIn::GlobalInvocationId
|
||||
| crate::BuiltIn::LocalInvocationId
|
||||
| crate::BuiltIn::WorkGroupId
|
||||
| crate::BuiltIn::WorkGroupSize => Some(crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
}),
|
||||
_ => None,
|
||||
};
|
||||
|
@ -25,24 +25,17 @@ impl crate::Module {
|
||||
return handle;
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let ty_flag = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::U32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let ty_scalar = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::F32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -51,8 +44,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -127,24 +119,17 @@ impl crate::Module {
|
||||
return handle;
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let ty_flag = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::U32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let ty_scalar = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::F32),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -152,9 +137,8 @@ impl crate::Module {
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
width,
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -162,10 +146,7 @@ impl crate::Module {
|
||||
let ty_bool = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
width: crate::BOOL_WIDTH,
|
||||
kind: crate::ScalarKind::Bool,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::BOOL),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -175,7 +156,7 @@ impl crate::Module {
|
||||
inner: crate::TypeInner::Matrix {
|
||||
columns: crate::VectorSize::Quad,
|
||||
rows: crate::VectorSize::Tri,
|
||||
width,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -277,28 +258,26 @@ impl crate::Module {
|
||||
}
|
||||
|
||||
let ty = match special_type {
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult { kind, width } => {
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult(scalar) => {
|
||||
let bool_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::BOOL),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
let scalar_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar { kind, width },
|
||||
inner: crate::TypeInner::Scalar(scalar),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
|
||||
crate::Type {
|
||||
name: Some(format!(
|
||||
"__atomic_compare_exchange_result<{kind:?},{width}>"
|
||||
"__atomic_compare_exchange_result<{:?},{}>",
|
||||
scalar.kind, scalar.width,
|
||||
)),
|
||||
inner: crate::TypeInner::Struct {
|
||||
members: vec![
|
||||
@ -323,10 +302,7 @@ impl crate::Module {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -337,8 +313,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -379,10 +354,7 @@ impl crate::Module {
|
||||
let float_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar::float(width)),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -390,10 +362,10 @@ impl crate::Module {
|
||||
let int_ty = self.types.insert(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Scalar {
|
||||
inner: crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
},
|
||||
}),
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
);
|
||||
@ -404,8 +376,7 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
@ -415,8 +386,10 @@ impl crate::Module {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width,
|
||||
},
|
||||
},
|
||||
},
|
||||
Span::UNDEFINED,
|
||||
|
@ -185,11 +185,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
ty_inner: &crate::TypeInner::Scalar { .. },
|
||||
..
|
||||
},
|
||||
Constructor::Type((_, &crate::TypeInner::Scalar { kind, width })),
|
||||
Constructor::Type((_, &crate::TypeInner::Scalar(scalar))),
|
||||
) => crate::Expression::As {
|
||||
expr: component,
|
||||
kind,
|
||||
convert: Some(width),
|
||||
kind: scalar.kind,
|
||||
convert: Some(scalar.width),
|
||||
},
|
||||
|
||||
// Vector conversion (vector -> vector)
|
||||
@ -203,14 +203,13 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
_,
|
||||
&crate::TypeInner::Vector {
|
||||
size: dst_size,
|
||||
kind: dst_kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
},
|
||||
)),
|
||||
) if dst_size == src_size => crate::Expression::As {
|
||||
expr: component,
|
||||
kind: dst_kind,
|
||||
convert: Some(dst_width),
|
||||
kind: dst_scalar.kind,
|
||||
convert: Some(dst_scalar.width),
|
||||
},
|
||||
|
||||
// Vector conversion (vector -> vector) - partial
|
||||
@ -294,23 +293,17 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::One {
|
||||
component,
|
||||
ty_inner:
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: src_kind,
|
||||
width: src_width,
|
||||
..
|
||||
},
|
||||
ty_inner: &crate::TypeInner::Scalar(src_scalar),
|
||||
..
|
||||
},
|
||||
Constructor::Type((
|
||||
_,
|
||||
&crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: dst_kind,
|
||||
width: dst_width,
|
||||
scalar: dst_scalar,
|
||||
},
|
||||
)),
|
||||
) if dst_kind == src_kind || dst_width == src_width => crate::Expression::Splat {
|
||||
) if dst_scalar == src_scalar => crate::Expression::Splat {
|
||||
size,
|
||||
value: component,
|
||||
},
|
||||
@ -320,8 +313,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner:
|
||||
&crate::TypeInner::Scalar { kind, width }
|
||||
| &crate::TypeInner::Vector { kind, width, .. },
|
||||
&crate::TypeInner::Scalar(scalar) | &crate::TypeInner::Vector { scalar, .. },
|
||||
..
|
||||
},
|
||||
Constructor::PartialVector { size },
|
||||
@ -333,9 +325,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
&crate::TypeInner::Scalar { .. } | &crate::TypeInner::Vector { .. },
|
||||
..
|
||||
},
|
||||
Constructor::Type((_, &crate::TypeInner::Vector { size, width, kind })),
|
||||
Constructor::Type((_, &crate::TypeInner::Vector { size, scalar })),
|
||||
) => {
|
||||
let inner = crate::TypeInner::Vector { size, kind, width };
|
||||
let inner = crate::TypeInner::Vector { size, scalar };
|
||||
let ty = ctx.ensure_type_exists(inner);
|
||||
crate::Expression::Compose { ty, components }
|
||||
}
|
||||
@ -344,7 +336,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner: &crate::TypeInner::Scalar { width, .. },
|
||||
first_component_ty_inner: &crate::TypeInner::Scalar(crate::Scalar { width, .. }),
|
||||
..
|
||||
},
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
@ -365,8 +357,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
)),
|
||||
) => {
|
||||
let vec_ty = ctx.ensure_type_exists(crate::TypeInner::Vector {
|
||||
width,
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar::float(width),
|
||||
size: rows,
|
||||
});
|
||||
|
||||
@ -395,7 +386,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
(
|
||||
Components::Many {
|
||||
components,
|
||||
first_component_ty_inner: &crate::TypeInner::Vector { width, .. },
|
||||
first_component_ty_inner:
|
||||
&crate::TypeInner::Vector {
|
||||
scalar: crate::Scalar { width, .. },
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
Constructor::PartialMatrix { columns, rows },
|
||||
|
@ -1413,22 +1413,19 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
};
|
||||
|
||||
let mut ectx = ctx.as_expression(block, &mut emitter);
|
||||
let (kind, width) = match *resolve_inner!(ectx, target_handle) {
|
||||
let scalar = match *resolve_inner!(ectx, target_handle) {
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
..
|
||||
} => (kind, width),
|
||||
size: None, scalar, ..
|
||||
} => scalar,
|
||||
crate::TypeInner::Pointer { base, .. } => match ectx.module.types[base].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => (kind, width),
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
},
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
};
|
||||
let literal = match kind {
|
||||
let literal = match scalar.kind {
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => {
|
||||
crate::Literal::one(kind, width)
|
||||
crate::Literal::one(scalar)
|
||||
.ok_or(Error::BadIncrDecrReferenceType(value_span))?
|
||||
}
|
||||
_ => return Err(Error::BadIncrDecrReferenceType(value_span)),
|
||||
@ -1608,21 +1605,17 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
match *inner {
|
||||
crate::TypeInner::Pointer { base, .. } => &ctx.module.types[base].inner,
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
..
|
||||
size: None, scalar, ..
|
||||
} => {
|
||||
temp_inner = crate::TypeInner::Scalar { kind, width };
|
||||
temp_inner = crate::TypeInner::Scalar(scalar);
|
||||
&temp_inner
|
||||
}
|
||||
crate::TypeInner::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
..
|
||||
} => {
|
||||
temp_inner = crate::TypeInner::Vector { size, kind, width };
|
||||
temp_inner = crate::TypeInner::Vector { size, scalar };
|
||||
&temp_inner
|
||||
}
|
||||
_ => unreachable!(
|
||||
@ -1679,9 +1672,9 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
let expr = self.expression(expr, ctx)?;
|
||||
let to_resolved = self.resolve_ast_type(to, &mut ctx.as_global())?;
|
||||
|
||||
let kind = match ctx.module.types[to_resolved].inner {
|
||||
crate::TypeInner::Scalar { kind, .. } => kind,
|
||||
crate::TypeInner::Vector { kind, .. } => kind,
|
||||
let element_scalar = match ctx.module.types[to_resolved].inner {
|
||||
crate::TypeInner::Scalar(scalar) => scalar,
|
||||
crate::TypeInner::Vector { scalar, .. } => scalar,
|
||||
_ => {
|
||||
let ty = resolve!(ctx, expr);
|
||||
return Err(Error::BadTypeCast {
|
||||
@ -1694,7 +1687,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
Typed::Plain(crate::Expression::As {
|
||||
expr,
|
||||
kind,
|
||||
kind: element_scalar.kind,
|
||||
convert: None,
|
||||
})
|
||||
}
|
||||
@ -1785,10 +1778,10 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
) && {
|
||||
matches!(
|
||||
resolve_inner!(ctx, argument),
|
||||
&crate::TypeInner::Scalar {
|
||||
&crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
..
|
||||
}
|
||||
})
|
||||
)
|
||||
};
|
||||
|
||||
@ -1828,10 +1821,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
|
||||
if fun == crate::MathFunction::Modf || fun == crate::MathFunction::Frexp {
|
||||
if let Some((size, width)) = match *resolve_inner!(ctx, arg) {
|
||||
crate::TypeInner::Scalar { width, .. } => Some((None, width)),
|
||||
crate::TypeInner::Vector { size, width, .. } => {
|
||||
Some((Some(size), width))
|
||||
crate::TypeInner::Scalar(crate::Scalar { width, .. }) => {
|
||||
Some((None, width))
|
||||
}
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
scalar: crate::Scalar { width, .. },
|
||||
..
|
||||
} => Some((Some(size), width)),
|
||||
_ => None,
|
||||
} {
|
||||
ctx.module.generate_predeclared_type(
|
||||
@ -1976,13 +1973,12 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
|
||||
args.finish()?;
|
||||
|
||||
let expression = match *resolve_inner!(ctx, value) {
|
||||
crate::TypeInner::Scalar { kind, width } => {
|
||||
crate::TypeInner::Scalar(scalar) => {
|
||||
crate::Expression::AtomicResult {
|
||||
ty: ctx.module.generate_predeclared_type(
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult {
|
||||
kind,
|
||||
width,
|
||||
},
|
||||
crate::PredeclaredType::AtomicCompareExchangeWeakResult(
|
||||
scalar,
|
||||
),
|
||||
),
|
||||
comparison: true,
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ use thiserror::Error;
|
||||
|
||||
pub use crate::front::wgsl::error::ParseError;
|
||||
use crate::front::wgsl::lower::Lowerer;
|
||||
use crate::Scalar;
|
||||
|
||||
pub struct Frontend {
|
||||
parser: Parser,
|
||||
@ -104,9 +105,8 @@ impl crate::TypeInner {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
match *self {
|
||||
Ti::Scalar { kind, width } => Scalar { kind, width }.to_wgsl(),
|
||||
Ti::Vector { size, kind, width } => {
|
||||
let scalar = Scalar { kind, width };
|
||||
Ti::Scalar(scalar) => scalar.to_wgsl(),
|
||||
Ti::Vector { size, scalar } => {
|
||||
format!("vec{}<{}>", size as u32, scalar.to_wgsl())
|
||||
}
|
||||
Ti::Matrix {
|
||||
@ -118,23 +118,19 @@ impl crate::TypeInner {
|
||||
"mat{}x{}<{}>",
|
||||
columns as u32,
|
||||
rows as u32,
|
||||
Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width
|
||||
}
|
||||
.to_wgsl(),
|
||||
Scalar::float(width).to_wgsl(),
|
||||
)
|
||||
}
|
||||
Ti::Atomic { kind, width } => {
|
||||
format!("atomic<{}>", Scalar { kind, width }.to_wgsl())
|
||||
Ti::Atomic(scalar) => {
|
||||
format!("atomic<{}>", scalar.to_wgsl())
|
||||
}
|
||||
Ti::Pointer { base, .. } => {
|
||||
let base = &gctx.types[base];
|
||||
let name = base.name.as_deref().unwrap_or("unknown");
|
||||
format!("ptr<{name}>")
|
||||
}
|
||||
Ti::ValuePointer { kind, width, .. } => {
|
||||
format!("ptr<{}>", Scalar { kind, width }.to_wgsl())
|
||||
Ti::ValuePointer { scalar, .. } => {
|
||||
format!("ptr<{}>", scalar.to_wgsl())
|
||||
}
|
||||
Ti::Array { base, size, .. } => {
|
||||
let member_type = &gctx.types[base];
|
||||
@ -292,16 +288,6 @@ mod type_inner_tests {
|
||||
}
|
||||
}
|
||||
|
||||
/// Characteristics of a scalar type.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Scalar {
|
||||
/// How the value's bits are to be interpreted.
|
||||
pub kind: crate::ScalarKind,
|
||||
|
||||
/// The size of the value in bytes.
|
||||
pub width: crate::Bytes,
|
||||
}
|
||||
|
||||
impl Scalar {
|
||||
/// Format a scalar kind+width as a type is written in wgsl.
|
||||
///
|
||||
@ -315,26 +301,4 @@ impl Scalar {
|
||||
};
|
||||
format!("{}{}", prefix, self.width * 8)
|
||||
}
|
||||
|
||||
const fn to_inner_scalar(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
|
||||
const fn to_inner_vector(self, size: crate::VectorSize) -> crate::TypeInner {
|
||||
crate::TypeInner::Vector {
|
||||
size,
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
|
||||
const fn to_inner_atomic(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Atomic {
|
||||
kind: self.kind,
|
||||
width: self.width,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -307,10 +307,7 @@ impl Parser {
|
||||
"vec2f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"vec3" => ast::ConstructorType::PartialVector {
|
||||
@ -319,28 +316,19 @@ impl Parser {
|
||||
"vec3i" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::I32,
|
||||
}))
|
||||
}
|
||||
"vec3u" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::U32,
|
||||
}))
|
||||
}
|
||||
"vec3f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"vec4" => ast::ConstructorType::PartialVector {
|
||||
@ -349,28 +337,19 @@ impl Parser {
|
||||
"vec4i" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::I32,
|
||||
}))
|
||||
}
|
||||
"vec4u" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::U32,
|
||||
}))
|
||||
}
|
||||
"vec4f" => {
|
||||
return Ok(Some(ast::ConstructorType::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
}))
|
||||
}
|
||||
"mat2x2" => ast::ConstructorType::PartialMatrix {
|
||||
@ -1109,10 +1088,7 @@ impl Parser {
|
||||
},
|
||||
"vec2f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"vec3" => {
|
||||
let scalar = lexer.next_scalar_generic()?;
|
||||
@ -1137,10 +1113,7 @@ impl Parser {
|
||||
},
|
||||
"vec3f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"vec4" => {
|
||||
let scalar = lexer.next_scalar_generic()?;
|
||||
@ -1165,10 +1138,7 @@ impl Parser {
|
||||
},
|
||||
"vec4f" => ast::Type::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
scalar: Scalar::F32,
|
||||
},
|
||||
"mat2x2" => {
|
||||
self.matrix_scalar_type(lexer, crate::VectorSize::Bi, crate::VectorSize::Bi)?
|
||||
|
@ -472,6 +472,19 @@ pub enum ScalarKind {
|
||||
Bool,
|
||||
}
|
||||
|
||||
/// Characteristics of a scalar type.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub struct Scalar {
|
||||
/// How the value's bits are to be interpreted.
|
||||
pub kind: ScalarKind,
|
||||
|
||||
/// This size of the value in bytes.
|
||||
pub width: Bytes,
|
||||
}
|
||||
|
||||
/// Size of an array.
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||
@ -677,13 +690,9 @@ pub struct Type {
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub enum TypeInner {
|
||||
/// Number of integral or floating-point kind.
|
||||
Scalar { kind: ScalarKind, width: Bytes },
|
||||
Scalar(Scalar),
|
||||
/// Vector of numbers.
|
||||
Vector {
|
||||
size: VectorSize,
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
},
|
||||
Vector { size: VectorSize, scalar: Scalar },
|
||||
/// Matrix of floats.
|
||||
Matrix {
|
||||
columns: VectorSize,
|
||||
@ -691,7 +700,7 @@ pub enum TypeInner {
|
||||
width: Bytes,
|
||||
},
|
||||
/// Atomic scalar.
|
||||
Atomic { kind: ScalarKind, width: Bytes },
|
||||
Atomic(Scalar),
|
||||
/// Pointer to another type.
|
||||
///
|
||||
/// Pointers to scalars and vectors should be treated as equivalent to
|
||||
@ -737,8 +746,7 @@ pub enum TypeInner {
|
||||
/// [`TypeResolution::Value`]: proc::TypeResolution::Value
|
||||
ValuePointer {
|
||||
size: Option<VectorSize>,
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
scalar: Scalar,
|
||||
space: AddressSpace,
|
||||
},
|
||||
|
||||
@ -1966,10 +1974,7 @@ pub struct EntryPoint {
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
#[cfg_attr(feature = "arbitrary", derive(Arbitrary))]
|
||||
pub enum PredeclaredType {
|
||||
AtomicCompareExchangeWeakResult {
|
||||
kind: ScalarKind,
|
||||
width: Bytes,
|
||||
},
|
||||
AtomicCompareExchangeWeakResult(Scalar),
|
||||
ModfResult {
|
||||
size: Option<VectorSize>,
|
||||
width: Bytes,
|
||||
|
@ -404,7 +404,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
let expr = self.check_and_get(expr)?;
|
||||
|
||||
match convert {
|
||||
Some(width) => self.cast(expr, kind, width, span),
|
||||
Some(width) => self.cast(expr, crate::Scalar { kind, width }, span),
|
||||
None => Err(ConstantEvaluatorError::NotImplemented(
|
||||
"bitcast built-in function".into(),
|
||||
)),
|
||||
@ -462,12 +462,11 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
match self.expressions[value] {
|
||||
Expression::Literal(literal) => {
|
||||
let kind = literal.scalar_kind();
|
||||
let width = literal.width();
|
||||
let scalar = literal.scalar();
|
||||
let ty = self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector { size, kind, width },
|
||||
inner: TypeInner::Vector { size, scalar },
|
||||
},
|
||||
span,
|
||||
);
|
||||
@ -479,7 +478,7 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
}
|
||||
Expression::ZeroValue(ty) => {
|
||||
let inner = match self.types[ty].inner {
|
||||
TypeInner::Scalar { kind, width } => TypeInner::Vector { size, kind, width },
|
||||
TypeInner::Scalar(scalar) => TypeInner::Vector { size, scalar },
|
||||
_ => return Err(ConstantEvaluatorError::SplatScalarOnly),
|
||||
};
|
||||
let res_ty = self.types.insert(Type { name: None, inner }, span);
|
||||
@ -498,14 +497,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
pattern: [crate::SwizzleComponent; 4],
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
let mut get_dst_ty = |ty| match self.types[ty].inner {
|
||||
crate::TypeInner::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => Ok(self.types.insert(
|
||||
crate::TypeInner::Vector { size: _, scalar } => Ok(self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector { size, kind, width },
|
||||
inner: crate::TypeInner::Vector { size, scalar },
|
||||
},
|
||||
span,
|
||||
)),
|
||||
@ -611,7 +606,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
&& matches!(
|
||||
self.types[ty0].inner,
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
) =>
|
||||
@ -709,7 +707,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
&& matches!(
|
||||
self.types[ty0].inner,
|
||||
crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
..
|
||||
},
|
||||
..
|
||||
}
|
||||
) =>
|
||||
@ -831,10 +832,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
Expression::ZeroValue(ty)
|
||||
if matches!(
|
||||
self.types[ty].inner,
|
||||
crate::TypeInner::Scalar {
|
||||
crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
) =>
|
||||
{
|
||||
Ok(0)
|
||||
@ -873,18 +874,17 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
span: Span,
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
match self.types[ty].inner {
|
||||
TypeInner::Scalar { kind, width } => {
|
||||
TypeInner::Scalar(scalar) => {
|
||||
let expr = Expression::Literal(
|
||||
Literal::zero(kind, width)
|
||||
.ok_or(ConstantEvaluatorError::TypeNotConstructible)?,
|
||||
Literal::zero(scalar).ok_or(ConstantEvaluatorError::TypeNotConstructible)?,
|
||||
);
|
||||
self.register_evaluated_expr(expr, span)
|
||||
}
|
||||
TypeInner::Vector { size, kind, width } => {
|
||||
TypeInner::Vector { size, scalar } => {
|
||||
let scalar_ty = self.types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar { kind, width },
|
||||
inner: TypeInner::Scalar(scalar),
|
||||
},
|
||||
span,
|
||||
);
|
||||
@ -905,8 +905,10 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
},
|
||||
},
|
||||
span,
|
||||
@ -943,43 +945,57 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert the scalar components of `expr` to `kind` and `target_width`.
|
||||
/// Convert the scalar components of `expr` to `target`.
|
||||
///
|
||||
/// Treat `span` as the location of the resulting expression.
|
||||
pub fn cast(
|
||||
&mut self,
|
||||
expr: Handle<Expression>,
|
||||
kind: ScalarKind,
|
||||
target_width: crate::Bytes,
|
||||
target: crate::Scalar,
|
||||
span: Span,
|
||||
) -> Result<Handle<Expression>, ConstantEvaluatorError> {
|
||||
use crate::Scalar as Sc;
|
||||
use crate::ScalarKind as Sk;
|
||||
|
||||
let expr = self.eval_zero_value_and_splat(expr, span)?;
|
||||
|
||||
let expr = match self.expressions[expr] {
|
||||
Expression::Literal(literal) => {
|
||||
let literal = match (kind, target_width) {
|
||||
(ScalarKind::Sint, 4) => Literal::I32(match literal {
|
||||
let literal = match target {
|
||||
Sc {
|
||||
kind: Sk::Sint,
|
||||
width: 4,
|
||||
} => Literal::I32(match literal {
|
||||
Literal::I32(v) => v,
|
||||
Literal::U32(v) => v as i32,
|
||||
Literal::F32(v) => v as i32,
|
||||
Literal::Bool(v) => v as i32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Uint, 4) => Literal::U32(match literal {
|
||||
Sc {
|
||||
kind: Sk::Uint,
|
||||
width: 4,
|
||||
} => Literal::U32(match literal {
|
||||
Literal::I32(v) => v as u32,
|
||||
Literal::U32(v) => v,
|
||||
Literal::F32(v) => v as u32,
|
||||
Literal::Bool(v) => v as u32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Float, 4) => Literal::F32(match literal {
|
||||
Sc {
|
||||
kind: Sk::Float,
|
||||
width: 4,
|
||||
} => Literal::F32(match literal {
|
||||
Literal::I32(v) => v as f32,
|
||||
Literal::U32(v) => v as f32,
|
||||
Literal::F32(v) => v,
|
||||
Literal::Bool(v) => v as u32 as f32,
|
||||
Literal::F64(_) => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
}),
|
||||
(ScalarKind::Bool, crate::BOOL_WIDTH) => Literal::Bool(match literal {
|
||||
Sc {
|
||||
kind: Sk::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
} => Literal::Bool(match literal {
|
||||
Literal::I32(v) => v != 0,
|
||||
Literal::U32(v) => v != 0,
|
||||
Literal::F32(v) => v != 0.0,
|
||||
@ -997,20 +1013,19 @@ impl<'a> ConstantEvaluator<'a> {
|
||||
let ty_inner = match self.types[ty].inner {
|
||||
TypeInner::Vector { size, .. } => TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: target_width,
|
||||
scalar: target,
|
||||
},
|
||||
TypeInner::Matrix { columns, rows, .. } => TypeInner::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width: target_width,
|
||||
width: target.width,
|
||||
},
|
||||
_ => return Err(ConstantEvaluatorError::InvalidCastArg),
|
||||
};
|
||||
|
||||
let mut components = src_components.clone();
|
||||
for component in &mut components {
|
||||
*component = self.cast(*component, kind, target_width, span)?;
|
||||
*component = self.cast(*component, target, span)?;
|
||||
}
|
||||
|
||||
let ty = self.types.insert(
|
||||
@ -1305,10 +1320,7 @@ mod tests {
|
||||
let scalar_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1318,8 +1330,10 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1441,10 +1455,7 @@ mod tests {
|
||||
let scalar_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1509,8 +1520,10 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Tri,
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1649,10 +1662,7 @@ mod tests {
|
||||
let i32_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1662,8 +1672,10 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
@ -1733,10 +1745,7 @@ mod tests {
|
||||
let i32_ty = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
@ -1746,8 +1755,10 @@ mod tests {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
size: VectorSize::Bi,
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
|
@ -171,17 +171,16 @@ impl Layouter {
|
||||
for (ty_handle, ty) in gctx.types.iter().skip(self.layouts.len()) {
|
||||
let size = ty.inner.size(gctx);
|
||||
let layout = match ty.inner {
|
||||
Ti::Scalar { width, .. } | Ti::Atomic { width, .. } => {
|
||||
let alignment = Alignment::new(width as u32)
|
||||
Ti::Scalar(scalar) | Ti::Atomic(scalar) => {
|
||||
let alignment = Alignment::new(scalar.width as u32)
|
||||
.ok_or(LayoutErrorInner::NonPowerOfTwoWidth.with(ty_handle))?;
|
||||
TypeLayout { size, alignment }
|
||||
}
|
||||
Ti::Vector {
|
||||
size: vec_size,
|
||||
width,
|
||||
..
|
||||
scalar,
|
||||
} => {
|
||||
let alignment = Alignment::new(width as u32)
|
||||
let alignment = Alignment::new(scalar.width as u32)
|
||||
.ok_or(LayoutErrorInner::NonPowerOfTwoWidth.with(ty_handle))?;
|
||||
TypeLayout {
|
||||
size,
|
||||
|
@ -77,6 +77,52 @@ impl super::ScalarKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Scalar {
|
||||
pub const I32: Self = Self {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
};
|
||||
pub const U32: Self = Self {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
};
|
||||
pub const F32: Self = Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
};
|
||||
pub const F64: Self = Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 8,
|
||||
};
|
||||
pub const BOOL: Self = Self {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
};
|
||||
|
||||
/// Construct a float `Scalar` with the given width.
|
||||
///
|
||||
/// This is especially common when dealing with
|
||||
/// `TypeInner::Matrix`, where the scalar kind is implicit.
|
||||
pub const fn float(width: crate::Bytes) -> Self {
|
||||
Self {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn to_inner_scalar(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar(self)
|
||||
}
|
||||
|
||||
pub const fn to_inner_vector(self, size: crate::VectorSize) -> crate::TypeInner {
|
||||
crate::TypeInner::Vector { size, scalar: self }
|
||||
}
|
||||
|
||||
pub const fn to_inner_atomic(self) -> crate::TypeInner {
|
||||
crate::TypeInner::Atomic(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for crate::Literal {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
match (*self, *other) {
|
||||
@ -118,8 +164,8 @@ impl std::hash::Hash for crate::Literal {
|
||||
}
|
||||
|
||||
impl crate::Literal {
|
||||
pub const fn new(value: u8, kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
match (value, kind, width) {
|
||||
pub const fn new(value: u8, scalar: crate::Scalar) -> Option<Self> {
|
||||
match (value, scalar.kind, scalar.width) {
|
||||
(value, crate::ScalarKind::Float, 8) => Some(Self::F64(value as _)),
|
||||
(value, crate::ScalarKind::Float, 4) => Some(Self::F32(value as _)),
|
||||
(value, crate::ScalarKind::Uint, 4) => Some(Self::U32(value as _)),
|
||||
@ -130,12 +176,12 @@ impl crate::Literal {
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn zero(kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
Self::new(0, kind, width)
|
||||
pub const fn zero(scalar: crate::Scalar) -> Option<Self> {
|
||||
Self::new(0, scalar)
|
||||
}
|
||||
|
||||
pub const fn one(kind: crate::ScalarKind, width: crate::Bytes) -> Option<Self> {
|
||||
Self::new(1, kind, width)
|
||||
pub const fn one(scalar: crate::Scalar) -> Option<Self> {
|
||||
Self::new(1, scalar)
|
||||
}
|
||||
|
||||
pub const fn width(&self) -> crate::Bytes {
|
||||
@ -145,44 +191,41 @@ impl crate::Literal {
|
||||
Self::Bool(_) => 1,
|
||||
}
|
||||
}
|
||||
pub const fn scalar_kind(&self) -> crate::ScalarKind {
|
||||
pub const fn scalar(&self) -> crate::Scalar {
|
||||
match *self {
|
||||
Self::F64(_) | Self::F32(_) => crate::ScalarKind::Float,
|
||||
Self::U32(_) => crate::ScalarKind::Uint,
|
||||
Self::I32(_) => crate::ScalarKind::Sint,
|
||||
Self::Bool(_) => crate::ScalarKind::Bool,
|
||||
crate::Literal::F64(_) => crate::Scalar::F64,
|
||||
crate::Literal::F32(_) => crate::Scalar::F32,
|
||||
crate::Literal::U32(_) => crate::Scalar::U32,
|
||||
crate::Literal::I32(_) => crate::Scalar::I32,
|
||||
crate::Literal::Bool(_) => crate::Scalar::BOOL,
|
||||
}
|
||||
}
|
||||
pub const fn scalar_kind(&self) -> crate::ScalarKind {
|
||||
self.scalar().kind
|
||||
}
|
||||
pub const fn ty_inner(&self) -> crate::TypeInner {
|
||||
crate::TypeInner::Scalar {
|
||||
kind: self.scalar_kind(),
|
||||
width: self.width(),
|
||||
}
|
||||
crate::TypeInner::Scalar(self.scalar())
|
||||
}
|
||||
}
|
||||
|
||||
pub const POINTER_SPAN: u32 = 4;
|
||||
|
||||
impl super::TypeInner {
|
||||
pub const fn scalar_kind(&self) -> Option<super::ScalarKind> {
|
||||
pub const fn scalar(&self) -> Option<super::Scalar> {
|
||||
use crate::TypeInner as Ti;
|
||||
match *self {
|
||||
super::TypeInner::Scalar { kind, .. } | super::TypeInner::Vector { kind, .. } => {
|
||||
Some(kind)
|
||||
}
|
||||
super::TypeInner::Matrix { .. } => Some(super::ScalarKind::Float),
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => Some(scalar),
|
||||
Ti::Matrix { width, .. } => Some(super::Scalar::float(width)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn scalar_width(&self) -> Option<u8> {
|
||||
// Multiply by 8 to get the bit width
|
||||
match *self {
|
||||
super::TypeInner::Scalar { width, .. } | super::TypeInner::Vector { width, .. } => {
|
||||
Some(width * 8)
|
||||
}
|
||||
super::TypeInner::Matrix { width, .. } => Some(width * 8),
|
||||
_ => None,
|
||||
}
|
||||
pub fn scalar_kind(&self) -> Option<super::ScalarKind> {
|
||||
self.scalar().map(|scalar| scalar.kind)
|
||||
}
|
||||
|
||||
pub fn scalar_width(&self) -> Option<u8> {
|
||||
self.scalar().map(|scalar| scalar.width * 8)
|
||||
}
|
||||
|
||||
pub const fn pointer_space(&self) -> Option<crate::AddressSpace> {
|
||||
@ -206,12 +249,8 @@ impl super::TypeInner {
|
||||
/// Get the size of this type.
|
||||
pub fn size(&self, _gctx: GlobalCtx) -> u32 {
|
||||
match *self {
|
||||
Self::Scalar { kind: _, width } | Self::Atomic { kind: _, width } => width as u32,
|
||||
Self::Vector {
|
||||
size,
|
||||
kind: _,
|
||||
width,
|
||||
} => size as u32 * width as u32,
|
||||
Self::Scalar(scalar) | Self::Atomic(scalar) => scalar.width as u32,
|
||||
Self::Vector { size, scalar } => size as u32 * scalar.width as u32,
|
||||
// matrices are treated as arrays of aligned columns
|
||||
Self::Matrix {
|
||||
columns,
|
||||
@ -255,16 +294,14 @@ impl super::TypeInner {
|
||||
use crate::TypeInner as Ti;
|
||||
match *self {
|
||||
Ti::Pointer { base, space } => match types[base].inner {
|
||||
Ti::Scalar { kind, width } => Some(Ti::ValuePointer {
|
||||
Ti::Scalar(scalar) => Some(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
Ti::Vector { size, kind, width } => Some(Ti::ValuePointer {
|
||||
Ti::Vector { size, scalar } => Some(Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
_ => None,
|
||||
@ -318,13 +355,10 @@ impl super::TypeInner {
|
||||
|
||||
pub fn component_type(&self, index: usize) -> Option<TypeResolution> {
|
||||
Some(match *self {
|
||||
Self::Vector { kind, width, .. } => {
|
||||
TypeResolution::Value(crate::TypeInner::Scalar { kind, width })
|
||||
}
|
||||
Self::Vector { scalar, .. } => TypeResolution::Value(crate::TypeInner::Scalar(scalar)),
|
||||
Self::Matrix { rows, width, .. } => TypeResolution::Value(crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
Self::Array {
|
||||
base,
|
||||
@ -628,7 +662,7 @@ impl GlobalCtx<'_> {
|
||||
match arena[handle] {
|
||||
crate::Expression::Literal(literal) => Some(literal),
|
||||
crate::Expression::ZeroValue(ty) => match gctx.types[ty].inner {
|
||||
crate::TypeInner::Scalar { kind, width } => crate::Literal::zero(kind, width),
|
||||
crate::TypeInner::Scalar(scalar) => crate::Literal::zero(scalar),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
|
@ -119,8 +119,8 @@ impl Clone for TypeResolution {
|
||||
match *self {
|
||||
Self::Handle(handle) => Self::Handle(handle),
|
||||
Self::Value(ref v) => Self::Value(match *v {
|
||||
Ti::Scalar { kind, width } => Ti::Scalar { kind, width },
|
||||
Ti::Vector { size, kind, width } => Ti::Vector { size, kind, width },
|
||||
Ti::Scalar(scalar) => Ti::Scalar(scalar),
|
||||
Ti::Vector { size, scalar } => Ti::Vector { size, scalar },
|
||||
Ti::Matrix {
|
||||
rows,
|
||||
columns,
|
||||
@ -133,13 +133,11 @@ impl Clone for TypeResolution {
|
||||
Ti::Pointer { base, space } => Ti::Pointer { base, space },
|
||||
Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
},
|
||||
_ => unreachable!("Unexpected clone type: {:?}", v),
|
||||
@ -243,36 +241,24 @@ impl<'a> ResolveContext<'a> {
|
||||
Ti::Array { base, .. } => TypeResolution::Handle(base),
|
||||
Ti::Matrix { rows, width, .. } => TypeResolution::Value(Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Vector { size: _, scalar } => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
Ti::ValuePointer {
|
||||
size: Some(_),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => TypeResolution::Value(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}),
|
||||
Ti::Pointer { base, space } => {
|
||||
TypeResolution::Value(match types[base].inner {
|
||||
Ti::Array { base, .. } => Ti::Pointer { base, space },
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => Ti::ValuePointer {
|
||||
Ti::Vector { size: _, scalar } => Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
},
|
||||
// Matrices are only dynamically indexed behind a pointer
|
||||
@ -281,9 +267,8 @@ impl<'a> ResolveContext<'a> {
|
||||
rows,
|
||||
width,
|
||||
} => Ti::ValuePointer {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size: Some(rows),
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
space,
|
||||
},
|
||||
Ti::BindingArray { base, .. } => Ti::Pointer { base, space },
|
||||
@ -307,11 +292,11 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
crate::Expression::AccessIndex { base, index } => {
|
||||
match *past(base)?.inner_with(types) {
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
if index >= size as u32 {
|
||||
return Err(ResolveError::OutOfBoundsIndex { expr: base, index });
|
||||
}
|
||||
TypeResolution::Value(Ti::Scalar { kind, width })
|
||||
TypeResolution::Value(Ti::Scalar(scalar))
|
||||
}
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
@ -323,8 +308,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
TypeResolution::Value(crate::TypeInner::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
})
|
||||
}
|
||||
Ti::Array { base, .. } => TypeResolution::Handle(base),
|
||||
@ -336,8 +320,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
if index >= size as u32 {
|
||||
@ -345,8 +328,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
TypeResolution::Value(Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
})
|
||||
}
|
||||
@ -355,14 +337,13 @@ impl<'a> ResolveContext<'a> {
|
||||
space,
|
||||
} => TypeResolution::Value(match types[ty_base].inner {
|
||||
Ti::Array { base, .. } => Ti::Pointer { base, space },
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
if index >= size as u32 {
|
||||
return Err(ResolveError::OutOfBoundsIndex { expr: base, index });
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
}
|
||||
}
|
||||
@ -376,8 +357,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: Some(rows),
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
space,
|
||||
}
|
||||
}
|
||||
@ -410,9 +390,7 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
}
|
||||
crate::Expression::Splat { size, value } => match *past(value)?.inner_with(types) {
|
||||
Ti::Scalar { kind, width } => {
|
||||
TypeResolution::Value(Ti::Vector { size, kind, width })
|
||||
}
|
||||
Ti::Scalar(scalar) => TypeResolution::Value(Ti::Vector { size, scalar }),
|
||||
ref other => {
|
||||
log::error!("Scalar type {:?}", other);
|
||||
return Err(ResolveError::InvalidScalar(value));
|
||||
@ -423,11 +401,9 @@ impl<'a> ResolveContext<'a> {
|
||||
vector,
|
||||
pattern: _,
|
||||
} => match *past(vector)?.inner_with(types) {
|
||||
Ti::Vector {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Vector { size, kind, width }),
|
||||
Ti::Vector { size: _, scalar } => {
|
||||
TypeResolution::Value(Ti::Vector { size, scalar })
|
||||
}
|
||||
ref other => {
|
||||
log::error!("Vector type {:?}", other);
|
||||
return Err(ResolveError::InvalidVector(vector));
|
||||
@ -464,20 +440,19 @@ impl<'a> ResolveContext<'a> {
|
||||
}
|
||||
crate::Expression::Load { pointer } => match *past(pointer)?.inner_with(types) {
|
||||
Ti::Pointer { base, space: _ } => {
|
||||
if let Ti::Atomic { kind, width } = types[base].inner {
|
||||
TypeResolution::Value(Ti::Scalar { kind, width })
|
||||
if let Ti::Atomic(scalar) = types[base].inner {
|
||||
TypeResolution::Value(Ti::Scalar(scalar))
|
||||
} else {
|
||||
TypeResolution::Handle(base)
|
||||
}
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => TypeResolution::Value(match size {
|
||||
Some(size) => Ti::Vector { size, kind, width },
|
||||
None => Ti::Scalar { kind, width },
|
||||
Some(size) => Ti::Vector { size, scalar },
|
||||
None => Ti::Scalar(scalar),
|
||||
}),
|
||||
ref other => {
|
||||
log::error!("Pointer type {:?}", other);
|
||||
@ -490,11 +465,13 @@ impl<'a> ResolveContext<'a> {
|
||||
..
|
||||
} => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { class, .. } => TypeResolution::Value(Ti::Vector {
|
||||
kind: match class {
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => kind,
|
||||
_ => crate::ScalarKind::Float,
|
||||
scalar: crate::Scalar {
|
||||
kind: match class {
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => kind,
|
||||
_ => crate::ScalarKind::Float,
|
||||
},
|
||||
width: 4,
|
||||
},
|
||||
width: 4,
|
||||
size: crate::VectorSize::Quad,
|
||||
}),
|
||||
ref other => {
|
||||
@ -505,18 +482,16 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::ImageSample { image, .. }
|
||||
| crate::Expression::ImageLoad { image, .. } => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { class, .. } => TypeResolution::Value(match class {
|
||||
crate::ImageClass::Depth { multi: _ } => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
},
|
||||
crate::ImageClass::Depth { multi: _ } => Ti::Scalar(crate::Scalar::F32),
|
||||
crate::ImageClass::Sampled { kind, multi: _ } => Ti::Vector {
|
||||
kind,
|
||||
width: 4,
|
||||
scalar: crate::Scalar { kind, width: 4 },
|
||||
size: crate::VectorSize::Quad,
|
||||
},
|
||||
crate::ImageClass::Storage { format, .. } => Ti::Vector {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
},
|
||||
size: crate::VectorSize::Quad,
|
||||
},
|
||||
}),
|
||||
@ -528,19 +503,14 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::ImageQuery { image, query } => TypeResolution::Value(match query {
|
||||
crate::ImageQuery::Size { level: _ } => match *past(image)?.inner_with(types) {
|
||||
Ti::Image { dim, .. } => match dim {
|
||||
crate::ImageDimension::D1 => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
crate::ImageDimension::D1 => Ti::Scalar(crate::Scalar::U32),
|
||||
crate::ImageDimension::D2 | crate::ImageDimension::Cube => Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
crate::ImageDimension::D3 => Ti::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
},
|
||||
ref other => {
|
||||
@ -550,10 +520,7 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
crate::ImageQuery::NumLevels
|
||||
| crate::ImageQuery::NumLayers
|
||||
| crate::ImageQuery::NumSamples => Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
},
|
||||
| crate::ImageQuery::NumSamples => Ti::Scalar(crate::Scalar::U32),
|
||||
}),
|
||||
crate::Expression::Unary { expr, .. } => past(expr)?.clone(),
|
||||
crate::Expression::Binary { op, left, right } => match op {
|
||||
@ -585,8 +552,7 @@ impl<'a> ResolveContext<'a> {
|
||||
&Ti::Vector { .. },
|
||||
) => TypeResolution::Value(Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
(
|
||||
&Ti::Vector { .. },
|
||||
@ -597,8 +563,7 @@ impl<'a> ResolveContext<'a> {
|
||||
},
|
||||
) => TypeResolution::Value(Ti::Vector {
|
||||
size: columns,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
}),
|
||||
(&Ti::Scalar { .. }, _) => res_right.clone(),
|
||||
(_, &Ti::Scalar { .. }) => res_left.clone(),
|
||||
@ -618,11 +583,10 @@ impl<'a> ResolveContext<'a> {
|
||||
| crate::BinaryOperator::GreaterEqual
|
||||
| crate::BinaryOperator::LogicalAnd
|
||||
| crate::BinaryOperator::LogicalOr => {
|
||||
let kind = crate::ScalarKind::Bool;
|
||||
let width = crate::BOOL_WIDTH;
|
||||
let scalar = crate::Scalar::BOOL;
|
||||
let inner = match *past(left)?.inner_with(types) {
|
||||
Ti::Scalar { .. } => Ti::Scalar { kind, width },
|
||||
Ti::Vector { size, .. } => Ti::Vector { size, kind, width },
|
||||
Ti::Scalar { .. } => Ti::Scalar(scalar),
|
||||
Ti::Vector { size, .. } => Ti::Vector { size, scalar },
|
||||
ref other => {
|
||||
return Err(ResolveError::IncompatibleOperands(format!(
|
||||
"{op:?}({other:?}, _)"
|
||||
@ -643,20 +607,13 @@ impl<'a> ResolveContext<'a> {
|
||||
crate::Expression::Derivative { expr, .. } => past(expr)?.clone(),
|
||||
crate::Expression::Relational { fun, argument } => match fun {
|
||||
crate::RelationalFunction::All | crate::RelationalFunction::Any => {
|
||||
TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
})
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL))
|
||||
}
|
||||
crate::RelationalFunction::IsNan | crate::RelationalFunction::IsInf => {
|
||||
match *past(argument)?.inner_with(types) {
|
||||
Ti::Scalar { .. } => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}),
|
||||
Ti::Scalar { .. } => TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL)),
|
||||
Ti::Vector { size, .. } => TypeResolution::Value(Ti::Vector {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
scalar: crate::Scalar::BOOL,
|
||||
size,
|
||||
}),
|
||||
ref other => {
|
||||
@ -714,14 +671,16 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Pow => res_arg.clone(),
|
||||
Mf::Modf | Mf::Frexp => {
|
||||
let (size, width) = match res_arg.inner_with(types) {
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
} => (None, width),
|
||||
&Ti::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size,
|
||||
width,
|
||||
}) => (None, width),
|
||||
&Ti::Vector {
|
||||
scalar: crate::Scalar {
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
},
|
||||
size,
|
||||
} => (Some(size), width),
|
||||
ref other =>
|
||||
return Err(ResolveError::IncompatibleOperands(format!("{fun:?}({other:?}, _)")))
|
||||
@ -740,10 +699,9 @@ impl<'a> ResolveContext<'a> {
|
||||
// geometry
|
||||
Mf::Dot => match *res_arg.inner_with(types) {
|
||||
Ti::Vector {
|
||||
kind,
|
||||
size: _,
|
||||
width,
|
||||
} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
scalar,
|
||||
} => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
ref other =>
|
||||
return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?}, _)")
|
||||
@ -754,7 +712,14 @@ impl<'a> ResolveContext<'a> {
|
||||
format!("{fun:?}(_, None)")
|
||||
))?;
|
||||
match (res_arg.inner_with(types), past(arg1)?.inner_with(types)) {
|
||||
(&Ti::Vector {kind: _, size: columns,width}, &Ti::Vector{ size: rows, .. }) => TypeResolution::Value(Ti::Matrix { columns, rows, width }),
|
||||
(
|
||||
&Ti::Vector { size: columns, scalar },
|
||||
&Ti::Vector{ size: rows, .. }
|
||||
) => TypeResolution::Value(Ti::Matrix {
|
||||
columns,
|
||||
rows,
|
||||
width: scalar.width
|
||||
}),
|
||||
(left, right) =>
|
||||
return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({left:?}, {right:?})")
|
||||
@ -764,8 +729,8 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Cross => res_arg.clone(),
|
||||
Mf::Distance |
|
||||
Mf::Length => match *res_arg.inner_with(types) {
|
||||
Ti::Scalar {width,kind} |
|
||||
Ti::Vector {width,kind,size:_} => TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Scalar(scalar) |
|
||||
Ti::Vector {scalar,size:_} => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -814,7 +779,7 @@ impl<'a> ResolveContext<'a> {
|
||||
Ti::Matrix {
|
||||
width,
|
||||
..
|
||||
} => TypeResolution::Value(Ti::Scalar { kind: crate::ScalarKind::Float, width }),
|
||||
} => TypeResolution::Value(Ti::Scalar(crate::Scalar::float(width))),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -828,10 +793,17 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::InsertBits |
|
||||
Mf::FindLsb |
|
||||
Mf::FindMsb => match *res_arg.inner_with(types) {
|
||||
Ti::Scalar { kind: kind @ (crate::ScalarKind::Sint | crate::ScalarKind::Uint), width } =>
|
||||
TypeResolution::Value(Ti::Scalar { kind, width }),
|
||||
Ti::Vector { size, kind: kind @ (crate::ScalarKind::Sint | crate::ScalarKind::Uint), width } =>
|
||||
TypeResolution::Value(Ti::Vector { size, kind, width }),
|
||||
Ti::Scalar(scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
}) => TypeResolution::Value(Ti::Scalar(scalar)),
|
||||
Ti::Vector {
|
||||
size,
|
||||
scalar: scalar @ crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
}
|
||||
} => TypeResolution::Value(Ti::Vector { size, scalar }),
|
||||
ref other => return Err(ResolveError::IncompatibleOperands(
|
||||
format!("{fun:?}({other:?})")
|
||||
)),
|
||||
@ -841,13 +813,19 @@ impl<'a> ResolveContext<'a> {
|
||||
Mf::Pack4x8unorm |
|
||||
Mf::Pack2x16snorm |
|
||||
Mf::Pack2x16unorm |
|
||||
Mf::Pack2x16float => TypeResolution::Value(Ti::Scalar { kind: crate::ScalarKind::Uint, width: 4 }),
|
||||
Mf::Pack2x16float => TypeResolution::Value(Ti::Scalar(crate::Scalar::U32)),
|
||||
// data unpacking
|
||||
Mf::Unpack4x8snorm |
|
||||
Mf::Unpack4x8unorm => TypeResolution::Value(Ti::Vector { size: crate::VectorSize::Quad, kind: crate::ScalarKind::Float, width: 4 }),
|
||||
Mf::Unpack4x8unorm => TypeResolution::Value(Ti::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
scalar: crate::Scalar::F32
|
||||
}),
|
||||
Mf::Unpack2x16snorm |
|
||||
Mf::Unpack2x16unorm |
|
||||
Mf::Unpack2x16float => TypeResolution::Value(Ti::Vector { size: crate::VectorSize::Bi, kind: crate::ScalarKind::Float, width: 4 }),
|
||||
Mf::Unpack2x16float => TypeResolution::Value(Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
scalar: crate::Scalar::F32
|
||||
}),
|
||||
}
|
||||
}
|
||||
crate::Expression::As {
|
||||
@ -855,18 +833,21 @@ impl<'a> ResolveContext<'a> {
|
||||
kind,
|
||||
convert,
|
||||
} => match *past(expr)?.inner_with(types) {
|
||||
Ti::Scalar { kind: _, width } => TypeResolution::Value(Ti::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
}),
|
||||
Ti::Scalar(crate::Scalar { width, .. }) => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
}))
|
||||
}
|
||||
Ti::Vector {
|
||||
kind: _,
|
||||
size,
|
||||
width,
|
||||
scalar: crate::Scalar { kind: _, width },
|
||||
} => TypeResolution::Value(Ti::Vector {
|
||||
kind,
|
||||
size,
|
||||
width: convert.unwrap_or(width),
|
||||
scalar: crate::Scalar {
|
||||
kind,
|
||||
width: convert.unwrap_or(width),
|
||||
},
|
||||
}),
|
||||
Ti::Matrix {
|
||||
columns,
|
||||
@ -890,14 +871,12 @@ impl<'a> ResolveContext<'a> {
|
||||
.ok_or(ResolveError::FunctionReturnsVoid)?;
|
||||
TypeResolution::Handle(result.ty)
|
||||
}
|
||||
crate::Expression::ArrayLength(_) => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Uint,
|
||||
width: 4,
|
||||
}),
|
||||
crate::Expression::RayQueryProceedResult => TypeResolution::Value(Ti::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}),
|
||||
crate::Expression::ArrayLength(_) => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::U32))
|
||||
}
|
||||
crate::Expression::RayQueryProceedResult => {
|
||||
TypeResolution::Value(Ti::Scalar(crate::Scalar::BOOL))
|
||||
}
|
||||
crate::Expression::RayQueryGetIntersection { .. } => {
|
||||
let result = self
|
||||
.special_types
|
||||
|
@ -159,10 +159,10 @@ impl ExpressionInfo {
|
||||
ref_count: 0,
|
||||
assignable_global: None,
|
||||
// this doesn't matter at this point, will be overwritten
|
||||
ty: TypeResolution::Value(crate::TypeInner::Scalar {
|
||||
ty: TypeResolution::Value(crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 0,
|
||||
}),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1070,8 +1070,7 @@ fn uniform_control_flow() {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width: 4,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
},
|
||||
Default::default(),
|
||||
|
@ -24,19 +24,15 @@ pub fn validate_compose(
|
||||
|
||||
match gctx.types[self_ty_handle].inner {
|
||||
// vectors are composed from scalars or other vectors
|
||||
Ti::Vector { size, kind, width } => {
|
||||
Ti::Vector { size, scalar } => {
|
||||
let mut total = 0;
|
||||
for (index, comp_res) in component_resolutions.enumerate() {
|
||||
total += match *comp_res.inner_with(gctx.types) {
|
||||
Ti::Scalar {
|
||||
kind: comp_kind,
|
||||
width: comp_width,
|
||||
} if comp_kind == kind && comp_width == width => 1,
|
||||
Ti::Scalar(comp_scalar) if comp_scalar == scalar => 1,
|
||||
Ti::Vector {
|
||||
size: comp_size,
|
||||
kind: comp_kind,
|
||||
width: comp_width,
|
||||
} if comp_kind == kind && comp_width == width => comp_size as u32,
|
||||
scalar: comp_scalar,
|
||||
} if comp_scalar == scalar => comp_size as u32,
|
||||
ref other => {
|
||||
log::error!("Vector component[{}] type {:?}", index, other);
|
||||
return Err(ComposeError::ComponentType {
|
||||
@ -60,8 +56,7 @@ pub fn validate_compose(
|
||||
} => {
|
||||
let inner = Ti::Vector {
|
||||
size: rows,
|
||||
kind: crate::ScalarKind::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::float(width),
|
||||
};
|
||||
if columns as usize != component_resolutions.len() {
|
||||
return Err(ComposeError::ComponentCount {
|
||||
|
@ -221,7 +221,7 @@ impl super::Validator {
|
||||
info: &FunctionInfo,
|
||||
mod_info: &ModuleInfo,
|
||||
) -> Result<ShaderStages, ExpressionError> {
|
||||
use crate::{Expression as E, ScalarKind as Sk, TypeInner as Ti};
|
||||
use crate::{Expression as E, Scalar as Sc, ScalarKind as Sk, TypeInner as Ti};
|
||||
|
||||
let resolver = ExpressionTypeResolver {
|
||||
root,
|
||||
@ -246,10 +246,10 @@ impl super::Validator {
|
||||
};
|
||||
match resolver[index] {
|
||||
//TODO: only allow one of these
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
..
|
||||
}) => {}
|
||||
ref other => {
|
||||
log::error!("Indexing by {:?}", other);
|
||||
return Err(ExpressionError::InvalidIndexType(index));
|
||||
@ -412,10 +412,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
..
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidImageArrayIndexType(expr)),
|
||||
}
|
||||
}
|
||||
@ -452,13 +452,15 @@ impl super::Validator {
|
||||
crate::ImageDimension::D3 | crate::ImageDimension::Cube => 3,
|
||||
};
|
||||
match resolver[coordinate] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => return Err(ExpressionError::InvalidImageCoordinateType(dim, coordinate)),
|
||||
}
|
||||
@ -466,11 +468,10 @@ impl super::Validator {
|
||||
// check constant offset
|
||||
if let Some(const_expr) = offset {
|
||||
match *mod_info[const_expr].inner_with(&module.types) {
|
||||
Ti::Scalar { kind: Sk::Sint, .. } if num_components == 1 => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Sint, .. }) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Sint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Sint, .. },
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleOffset(dim, const_expr));
|
||||
@ -481,9 +482,9 @@ impl super::Validator {
|
||||
// check depth reference type
|
||||
if let Some(expr) = depth_ref {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidDepthReference(expr)),
|
||||
}
|
||||
match level {
|
||||
@ -518,44 +519,48 @@ impl super::Validator {
|
||||
crate::SampleLevel::Zero => ShaderStages::all(),
|
||||
crate::SampleLevel::Exact(expr) => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidSampleLevelExactType(expr)),
|
||||
}
|
||||
ShaderStages::all()
|
||||
}
|
||||
crate::SampleLevel::Bias(expr) => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidSampleLevelBiasType(expr)),
|
||||
}
|
||||
ShaderStages::FRAGMENT
|
||||
}
|
||||
crate::SampleLevel::Gradient { x, y } => {
|
||||
match resolver[x] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleLevelGradientType(dim, x))
|
||||
}
|
||||
}
|
||||
match resolver[y] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} if num_components == 1 => {}
|
||||
}) if num_components == 1 => {}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} if size as u32 == num_components => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidSampleLevelGradientType(dim, y))
|
||||
@ -592,10 +597,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => return Err(ExpressionError::InvalidImageArrayIndexType(expr)),
|
||||
}
|
||||
}
|
||||
@ -669,7 +674,7 @@ impl super::Validator {
|
||||
let right_inner = &resolver[right];
|
||||
let good = match op {
|
||||
Bo::Add | Bo::Subtract => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -677,7 +682,7 @@ impl super::Validator {
|
||||
_ => false,
|
||||
},
|
||||
Bo::Divide | Bo::Modulo => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -690,52 +695,62 @@ impl super::Validator {
|
||||
};
|
||||
let types_match = match (left_inner, right_inner) {
|
||||
// Straight scalar and mixed scalar/vector.
|
||||
(&Ti::Scalar { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Vector { kind: kind1, .. }, &Ti::Scalar { kind: kind2, .. })
|
||||
| (&Ti::Scalar { kind: kind1, .. }, &Ti::Vector { kind: kind2, .. }) => {
|
||||
kind1 == kind2
|
||||
}
|
||||
(&Ti::Scalar(scalar1), &Ti::Scalar(scalar2))
|
||||
| (
|
||||
&Ti::Vector {
|
||||
scalar: scalar1, ..
|
||||
},
|
||||
&Ti::Scalar(scalar2),
|
||||
)
|
||||
| (
|
||||
&Ti::Scalar(scalar1),
|
||||
&Ti::Vector {
|
||||
scalar: scalar2, ..
|
||||
},
|
||||
) => scalar1 == scalar2,
|
||||
// Scalar/matrix.
|
||||
(
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
}),
|
||||
&Ti::Matrix { .. },
|
||||
)
|
||||
| (
|
||||
&Ti::Matrix { .. },
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
}),
|
||||
) => true,
|
||||
// Vector/vector.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: kind1,
|
||||
size: size1,
|
||||
..
|
||||
scalar: scalar1,
|
||||
},
|
||||
&Ti::Vector {
|
||||
kind: kind2,
|
||||
size: size2,
|
||||
..
|
||||
scalar: scalar2,
|
||||
},
|
||||
) => kind1 == kind2 && size1 == size2,
|
||||
) => scalar1 == scalar2 && size1 == size2,
|
||||
// Matrix * vector.
|
||||
(
|
||||
&Ti::Matrix { columns, .. },
|
||||
&Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
size,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
},
|
||||
) => columns == size,
|
||||
// Vector * matrix.
|
||||
(
|
||||
&Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
size,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
},
|
||||
&Ti::Matrix { rows, .. },
|
||||
) => size == rows,
|
||||
@ -744,24 +759,14 @@ impl super::Validator {
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
let left_width = match *left_inner {
|
||||
Ti::Scalar { width, .. }
|
||||
| Ti::Vector { width, .. }
|
||||
| Ti::Matrix { width, .. } => width,
|
||||
_ => 0,
|
||||
};
|
||||
let right_width = match *right_inner {
|
||||
Ti::Scalar { width, .. }
|
||||
| Ti::Vector { width, .. }
|
||||
| Ti::Matrix { width, .. } => width,
|
||||
_ => 0,
|
||||
};
|
||||
let left_width = left_inner.scalar_width().unwrap_or(0);
|
||||
let right_width = right_inner.scalar_width().unwrap_or(0);
|
||||
kind_allowed && types_match && left_width == right_width
|
||||
}
|
||||
Bo::Equal | Bo::NotEqual => left_inner.is_sized() && left_inner == right_inner,
|
||||
Bo::Less | Bo::LessEqual | Bo::Greater | Bo::GreaterEqual => {
|
||||
match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Uint | Sk::Sint | Sk::Float => left_inner == right_inner,
|
||||
Sk::Bool => false,
|
||||
},
|
||||
@ -772,16 +777,18 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
Bo::LogicalAnd | Bo::LogicalOr => match *left_inner {
|
||||
Ti::Scalar { kind: Sk::Bool, .. } | Ti::Vector { kind: Sk::Bool, .. } => {
|
||||
left_inner == right_inner
|
||||
}
|
||||
Ti::Scalar(Sc { kind: Sk::Bool, .. })
|
||||
| Ti::Vector {
|
||||
scalar: Sc { kind: Sk::Bool, .. },
|
||||
..
|
||||
} => left_inner == right_inner,
|
||||
ref other => {
|
||||
log::error!("Op {:?} left type {:?}", op, other);
|
||||
false
|
||||
}
|
||||
},
|
||||
Bo::And | Bo::InclusiveOr => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Bool | Sk::Sint | Sk::Uint => left_inner == right_inner,
|
||||
Sk::Float => false,
|
||||
},
|
||||
@ -791,7 +798,7 @@ impl super::Validator {
|
||||
}
|
||||
},
|
||||
Bo::ExclusiveOr => match *left_inner {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => match kind {
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => match scalar.kind {
|
||||
Sk::Sint | Sk::Uint => left_inner == right_inner,
|
||||
Sk::Bool | Sk::Float => false,
|
||||
},
|
||||
@ -801,27 +808,26 @@ impl super::Validator {
|
||||
}
|
||||
},
|
||||
Bo::ShiftLeft | Bo::ShiftRight => {
|
||||
let (base_size, base_kind) = match *left_inner {
|
||||
Ti::Scalar { kind, .. } => (Ok(None), kind),
|
||||
Ti::Vector { size, kind, .. } => (Ok(Some(size)), kind),
|
||||
let (base_size, base_scalar) = match *left_inner {
|
||||
Ti::Scalar(scalar) => (Ok(None), scalar),
|
||||
Ti::Vector { size, scalar } => (Ok(Some(size)), scalar),
|
||||
ref other => {
|
||||
log::error!("Op {:?} base type {:?}", op, other);
|
||||
(Err(()), Sk::Bool)
|
||||
(Err(()), Sc::BOOL)
|
||||
}
|
||||
};
|
||||
let shift_size = match *right_inner {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => Ok(None),
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => Ok(None),
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Uint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Uint, .. },
|
||||
} => Ok(Some(size)),
|
||||
ref other => {
|
||||
log::error!("Op {:?} shift type {:?}", op, other);
|
||||
Err(())
|
||||
}
|
||||
};
|
||||
match base_kind {
|
||||
match base_scalar.kind {
|
||||
Sk::Sint | Sk::Uint => base_size.is_ok() && base_size == shift_size,
|
||||
Sk::Float | Sk::Bool => false,
|
||||
}
|
||||
@ -850,10 +856,10 @@ impl super::Validator {
|
||||
let accept_inner = &resolver[accept];
|
||||
let reject_inner = &resolver[reject];
|
||||
let condition_good = match resolver[condition] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
} => {
|
||||
}) => {
|
||||
// When `condition` is a single boolean, `accept` and
|
||||
// `reject` can be vectors or scalars.
|
||||
match *accept_inner {
|
||||
@ -863,8 +869,11 @@ impl super::Validator {
|
||||
}
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Bool,
|
||||
width: _,
|
||||
},
|
||||
} => match *accept_inner {
|
||||
Ti::Vector {
|
||||
size: other_size, ..
|
||||
@ -880,11 +889,15 @@ impl super::Validator {
|
||||
}
|
||||
E::Derivative { expr, .. } => {
|
||||
match resolver[expr] {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidDerivative),
|
||||
}
|
||||
@ -895,19 +908,18 @@ impl super::Validator {
|
||||
let argument_inner = &resolver[argument];
|
||||
match fun {
|
||||
Rf::All | Rf::Any => match *argument_inner {
|
||||
Ti::Vector { kind: Sk::Bool, .. } => {}
|
||||
Ti::Vector {
|
||||
scalar: Sc { kind: Sk::Bool, .. },
|
||||
..
|
||||
} => {}
|
||||
ref other => {
|
||||
log::error!("All/Any of type {:?}", other);
|
||||
return Err(ExpressionError::InvalidBooleanVector(argument));
|
||||
}
|
||||
},
|
||||
Rf::IsNan | Rf::IsInf => match *argument_inner {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
ref other => {
|
||||
log::error!("Float test of type {:?}", other);
|
||||
return Err(ExpressionError::InvalidFloatArgument(argument));
|
||||
@ -936,7 +948,9 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -949,7 +963,9 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -969,7 +985,9 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let good = match *arg_ty {
|
||||
Ti::Scalar { kind, .. } | Ti::Vector { kind, .. } => kind != Sk::Bool,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. } => {
|
||||
scalar.kind != Sk::Bool
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -1021,12 +1039,8 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
}
|
||||
@ -1035,12 +1049,16 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float | Sk::Sint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1052,12 +1070,8 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
} => {}
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
if arg1_ty != arg_ty {
|
||||
@ -1072,16 +1086,10 @@ impl super::Validator {
|
||||
if arg1_ty.is_some() || arg2_ty.is_some() || arg3_ty.is_some() {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
if !matches!(
|
||||
*arg_ty,
|
||||
Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
..
|
||||
} | Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
..
|
||||
},
|
||||
) {
|
||||
if !matches!(*arg_ty,
|
||||
Ti::Scalar(scalar) | Ti::Vector { scalar, .. }
|
||||
if scalar.kind == Sk::Float)
|
||||
{
|
||||
return Err(ExpressionError::InvalidArgumentType(fun, 1, arg));
|
||||
}
|
||||
}
|
||||
@ -1091,24 +1099,25 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let size0 = match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
} => None,
|
||||
}) => None,
|
||||
Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
size,
|
||||
..
|
||||
} => Some(size),
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(fun, 0, arg));
|
||||
}
|
||||
};
|
||||
let good = match *arg1_ty {
|
||||
Ti::Scalar { kind: Sk::Sint, .. } if size0.is_none() => true,
|
||||
Ti::Scalar(Sc { kind: Sk::Sint, .. }) if size0.is_none() => true,
|
||||
Ti::Vector {
|
||||
size,
|
||||
kind: Sk::Sint,
|
||||
..
|
||||
scalar: Sc { kind: Sk::Sint, .. },
|
||||
} if Some(size) == size0 => true,
|
||||
_ => false,
|
||||
};
|
||||
@ -1127,7 +1136,11 @@ impl super::Validator {
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float | Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float | Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1147,7 +1160,11 @@ impl super::Validator {
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1167,7 +1184,11 @@ impl super::Validator {
|
||||
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1183,13 +1204,17 @@ impl super::Validator {
|
||||
match (arg_ty, arg2_ty) {
|
||||
(
|
||||
&Ti::Vector {
|
||||
width: vector_width,
|
||||
scalar:
|
||||
Sc {
|
||||
width: vector_width,
|
||||
..
|
||||
},
|
||||
..
|
||||
},
|
||||
&Ti::Scalar {
|
||||
&Ti::Scalar(Sc {
|
||||
width: scalar_width,
|
||||
kind: Sk::Float,
|
||||
},
|
||||
}),
|
||||
) if vector_width == scalar_width => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
@ -1206,7 +1231,11 @@ impl super::Validator {
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1217,11 +1246,15 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float, ..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float, ..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1246,13 +1279,16 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
let arg_width = match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
..
|
||||
} => width,
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1266,10 +1302,10 @@ impl super::Validator {
|
||||
}
|
||||
// the last argument can always be a scalar
|
||||
match *arg2_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
} if width == arg_width => {}
|
||||
}) if width == arg_width => {}
|
||||
_ if arg2_ty == arg_ty => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
@ -1311,12 +1347,16 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1328,12 +1368,16 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
@ -1346,7 +1390,7 @@ impl super::Validator {
|
||||
));
|
||||
}
|
||||
match *arg2_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1356,7 +1400,7 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
match *arg3_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1372,18 +1416,22 @@ impl super::Validator {
|
||||
_ => return Err(ExpressionError::WrongArgumentCount(fun)),
|
||||
};
|
||||
match *arg_ty {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
}
|
||||
})
|
||||
| Ti::Vector {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Sint | Sk::Uint,
|
||||
..
|
||||
},
|
||||
..
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
match *arg1_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1393,7 +1441,7 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
match *arg2_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => {
|
||||
return Err(ExpressionError::InvalidArgumentType(
|
||||
fun,
|
||||
@ -1410,8 +1458,10 @@ impl super::Validator {
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1423,8 +1473,10 @@ impl super::Validator {
|
||||
match *arg_ty {
|
||||
Ti::Vector {
|
||||
size: crate::VectorSize::Quad,
|
||||
kind: Sk::Float,
|
||||
..
|
||||
scalar:
|
||||
Sc {
|
||||
kind: Sk::Float, ..
|
||||
},
|
||||
} => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
@ -1438,7 +1490,7 @@ impl super::Validator {
|
||||
return Err(ExpressionError::WrongArgumentCount(fun));
|
||||
}
|
||||
match *arg_ty {
|
||||
Ti::Scalar { kind: Sk::Uint, .. } => {}
|
||||
Ti::Scalar(Sc { kind: Sk::Uint, .. }) => {}
|
||||
_ => return Err(ExpressionError::InvalidArgumentType(fun, 0, arg)),
|
||||
}
|
||||
}
|
||||
@ -1450,14 +1502,18 @@ impl super::Validator {
|
||||
kind,
|
||||
convert,
|
||||
} => {
|
||||
let base_width = match resolver[expr] {
|
||||
crate::TypeInner::Scalar { width, .. }
|
||||
| crate::TypeInner::Vector { width, .. }
|
||||
| crate::TypeInner::Matrix { width, .. } => width,
|
||||
let mut base_scalar = match resolver[expr] {
|
||||
crate::TypeInner::Scalar(scalar) | crate::TypeInner::Vector { scalar, .. } => {
|
||||
scalar
|
||||
}
|
||||
crate::TypeInner::Matrix { width, .. } => crate::Scalar::float(width),
|
||||
_ => return Err(ExpressionError::InvalidCastArgument),
|
||||
};
|
||||
let width = convert.unwrap_or(base_width);
|
||||
if self.check_width(kind, width).is_err() {
|
||||
base_scalar.kind = kind;
|
||||
if let Some(width) = convert {
|
||||
base_scalar.width = width;
|
||||
}
|
||||
if self.check_width(base_scalar).is_err() {
|
||||
return Err(ExpressionError::InvalidCastArgument);
|
||||
}
|
||||
ShaderStages::all()
|
||||
@ -1465,10 +1521,12 @@ impl super::Validator {
|
||||
E::CallResult(function) => mod_info.functions[function.index()].available_stages,
|
||||
E::AtomicResult { ty, comparison } => {
|
||||
let scalar_predicate = |ty: &crate::TypeInner| match ty {
|
||||
&crate::TypeInner::Scalar {
|
||||
kind: kind @ (crate::ScalarKind::Uint | crate::ScalarKind::Sint),
|
||||
width,
|
||||
} => self.check_width(kind, width).is_ok(),
|
||||
&crate::TypeInner::Scalar(
|
||||
scalar @ Sc {
|
||||
kind: crate::ScalarKind::Uint | crate::ScalarKind::Sint,
|
||||
..
|
||||
},
|
||||
) => self.check_width(scalar).is_ok(),
|
||||
_ => false,
|
||||
};
|
||||
let good = match &module.types[ty].inner {
|
||||
@ -1569,9 +1627,7 @@ impl super::Validator {
|
||||
}
|
||||
|
||||
pub fn validate_literal(&self, literal: crate::Literal) -> Result<(), LiteralError> {
|
||||
let kind = literal.scalar_kind();
|
||||
let width = literal.width();
|
||||
self.check_width(kind, width)?;
|
||||
self.check_width(literal.scalar())?;
|
||||
check_literal_value(literal)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -345,9 +345,9 @@ impl super::Validator {
|
||||
context: &BlockContext,
|
||||
) -> Result<(), WithSpan<FunctionError>> {
|
||||
let pointer_inner = context.resolve_type(pointer, &self.valid_expression_set)?;
|
||||
let (ptr_kind, ptr_width) = match *pointer_inner {
|
||||
let ptr_scalar = match *pointer_inner {
|
||||
crate::TypeInner::Pointer { base, .. } => match context.types[base].inner {
|
||||
crate::TypeInner::Atomic { kind, width } => (kind, width),
|
||||
crate::TypeInner::Atomic(scalar) => scalar,
|
||||
ref other => {
|
||||
log::error!("Atomic pointer to type {:?}", other);
|
||||
return Err(AtomicError::InvalidPointer(pointer)
|
||||
@ -365,7 +365,7 @@ impl super::Validator {
|
||||
|
||||
let value_inner = context.resolve_type(value, &self.valid_expression_set)?;
|
||||
match *value_inner {
|
||||
crate::TypeInner::Scalar { width, kind } if kind == ptr_kind && width == ptr_width => {}
|
||||
crate::TypeInner::Scalar(scalar) if scalar == ptr_scalar => {}
|
||||
ref other => {
|
||||
log::error!("Atomic operand type {:?}", other);
|
||||
return Err(AtomicError::InvalidOperand(value)
|
||||
@ -387,12 +387,8 @@ impl super::Validator {
|
||||
match context.expressions[result] {
|
||||
crate::Expression::AtomicResult { ty, comparison }
|
||||
if {
|
||||
let scalar_predicate = |ty: &crate::TypeInner| {
|
||||
*ty == crate::TypeInner::Scalar {
|
||||
kind: ptr_kind,
|
||||
width: ptr_width,
|
||||
}
|
||||
};
|
||||
let scalar_predicate =
|
||||
|ty: &crate::TypeInner| *ty == crate::TypeInner::Scalar(ptr_scalar);
|
||||
match &context.types[ty].inner {
|
||||
ty if !comparison => scalar_predicate(ty),
|
||||
&crate::TypeInner::Struct { ref members, .. } if comparison => {
|
||||
@ -445,10 +441,10 @@ impl super::Validator {
|
||||
ref reject,
|
||||
} => {
|
||||
match *context.resolve_type(condition, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidIfType(condition)
|
||||
.with_span_handle(condition, context.expressions))
|
||||
@ -560,10 +556,10 @@ impl super::Validator {
|
||||
|
||||
if let Some(condition) = break_if {
|
||||
match *context.resolve_type(condition, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidIfType(condition)
|
||||
.with_span_handle(condition, context.expressions))
|
||||
@ -665,21 +661,19 @@ impl super::Validator {
|
||||
|
||||
let good = match *pointer_ty {
|
||||
Ti::Pointer { base, space: _ } => match context.types[base].inner {
|
||||
Ti::Atomic { kind, width } => *value_ty == Ti::Scalar { kind, width },
|
||||
Ti::Atomic(scalar) => *value_ty == Ti::Scalar(scalar),
|
||||
ref other => value_ty == other,
|
||||
},
|
||||
Ti::ValuePointer {
|
||||
size: Some(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => *value_ty == Ti::Vector { size, kind, width },
|
||||
} => *value_ty == Ti::Vector { size, scalar },
|
||||
Ti::ValuePointer {
|
||||
size: None,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space: _,
|
||||
} => *value_ty == Ti::Scalar { kind, width },
|
||||
} => *value_ty == Ti::Scalar(scalar),
|
||||
_ => false,
|
||||
};
|
||||
if !good {
|
||||
@ -768,10 +762,10 @@ impl super::Validator {
|
||||
}
|
||||
if let Some(expr) = array_index {
|
||||
match *context.resolve_type(expr, &self.valid_expression_set)? {
|
||||
Ti::Scalar {
|
||||
Ti::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
width: _,
|
||||
} => {}
|
||||
}) => {}
|
||||
_ => {
|
||||
return Err(FunctionError::InvalidImageStore(
|
||||
ExpressionError::InvalidImageArrayIndexType(expr),
|
||||
@ -783,9 +777,11 @@ impl super::Validator {
|
||||
match class {
|
||||
crate::ImageClass::Storage { format, .. } => {
|
||||
crate::TypeInner::Vector {
|
||||
kind: format.into(),
|
||||
size: crate::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: crate::Scalar {
|
||||
kind: format.into(),
|
||||
width: 4,
|
||||
},
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -678,10 +678,7 @@ fn constant_deps() {
|
||||
let i32_handle = types.insert(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Sint,
|
||||
width: 4,
|
||||
},
|
||||
inner: TypeInner::Scalar(crate::Scalar::I32),
|
||||
},
|
||||
nowhere,
|
||||
);
|
||||
|
@ -142,9 +142,7 @@ impl VaryingContext<'_> {
|
||||
ty: Handle<crate::Type>,
|
||||
binding: &crate::Binding,
|
||||
) -> Result<(), VaryingError> {
|
||||
use crate::{
|
||||
BuiltIn as Bi, ScalarKind as Sk, ShaderStage as St, TypeInner as Ti, VectorSize as Vs,
|
||||
};
|
||||
use crate::{BuiltIn as Bi, ShaderStage as St, TypeInner as Ti, VectorSize as Vs};
|
||||
|
||||
let ty_inner = &self.types[ty].inner;
|
||||
match *binding {
|
||||
@ -174,44 +172,30 @@ impl VaryingContext<'_> {
|
||||
return Err(VaryingError::UnsupportedCapability(required));
|
||||
}
|
||||
|
||||
let width = 4;
|
||||
let (visible, type_good) = match built_in {
|
||||
Bi::BaseInstance | Bi::BaseVertex | Bi::InstanceIndex | Bi::VertexIndex => (
|
||||
self.stage == St::Vertex && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::ClipDistance | Bi::CullDistance => (
|
||||
self.stage == St::Vertex && self.output,
|
||||
match *ty_inner {
|
||||
Ti::Array { base, .. } => {
|
||||
self.types[base].inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
}
|
||||
self.types[base].inner == Ti::Scalar(crate::Scalar::F32)
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
),
|
||||
Bi::PointSize => (
|
||||
self.stage == St::Vertex && self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::F32),
|
||||
),
|
||||
Bi::PointCoord => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Bi,
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
),
|
||||
Bi::Position { .. } => (
|
||||
@ -223,8 +207,7 @@ impl VaryingContext<'_> {
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Quad,
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
scalar: crate::Scalar::F32,
|
||||
},
|
||||
),
|
||||
Bi::ViewIndex => (
|
||||
@ -232,59 +215,31 @@ impl VaryingContext<'_> {
|
||||
St::Vertex | St::Fragment => !self.output,
|
||||
St::Compute => false,
|
||||
},
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Sint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::I32),
|
||||
),
|
||||
Bi::FragDepth => (
|
||||
self.stage == St::Fragment && self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Float,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::F32),
|
||||
),
|
||||
Bi::FrontFacing => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::BOOL),
|
||||
),
|
||||
Bi::PrimitiveIndex => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::SampleIndex => (
|
||||
self.stage == St::Fragment && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::SampleMask => (
|
||||
self.stage == St::Fragment,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::LocalInvocationIndex => (
|
||||
self.stage == St::Compute && !self.output,
|
||||
*ty_inner
|
||||
== Ti::Scalar {
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
},
|
||||
*ty_inner == Ti::Scalar(crate::Scalar::U32),
|
||||
),
|
||||
Bi::GlobalInvocationId
|
||||
| Bi::LocalInvocationId
|
||||
@ -295,8 +250,7 @@ impl VaryingContext<'_> {
|
||||
*ty_inner
|
||||
== Ti::Vector {
|
||||
size: Vs::Tri,
|
||||
kind: Sk::Uint,
|
||||
width,
|
||||
scalar: crate::Scalar::U32,
|
||||
},
|
||||
),
|
||||
};
|
||||
|
@ -264,19 +264,25 @@ impl crate::TypeInner {
|
||||
#[cfg(feature = "validate")]
|
||||
const fn image_storage_coordinates(&self) -> Option<crate::ImageDimension> {
|
||||
match *self {
|
||||
Self::Scalar {
|
||||
Self::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
} => Some(crate::ImageDimension::D1),
|
||||
}) => Some(crate::ImageDimension::D1),
|
||||
Self::Vector {
|
||||
size: crate::VectorSize::Bi,
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(crate::ImageDimension::D2),
|
||||
Self::Vector {
|
||||
size: crate::VectorSize::Tri,
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
scalar:
|
||||
crate::Scalar {
|
||||
kind: crate::ScalarKind::Sint | crate::ScalarKind::Uint,
|
||||
..
|
||||
},
|
||||
} => Some(crate::ImageDimension::D3),
|
||||
_ => None,
|
||||
}
|
||||
@ -349,10 +355,11 @@ impl Validator {
|
||||
ValidationError::from(e).with_span_handle(handle, &module.types)
|
||||
})?;
|
||||
|
||||
let placeholder = TypeResolution::Value(crate::TypeInner::Scalar {
|
||||
// These should all get overwritten.
|
||||
let placeholder = TypeResolution::Value(crate::TypeInner::Scalar(crate::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: 0,
|
||||
});
|
||||
}));
|
||||
|
||||
let mut mod_info = ModuleInfo {
|
||||
type_flags: Vec::with_capacity(module.types.len()),
|
||||
@ -482,9 +489,5 @@ fn validate_atomic_compare_exchange_struct(
|
||||
&& members[0].name.as_deref() == Some("old_value")
|
||||
&& scalar_predicate(&types[members[0].ty].inner)
|
||||
&& members[1].name.as_deref() == Some("exchanged")
|
||||
&& types[members[1].ty].inner
|
||||
== crate::TypeInner::Scalar {
|
||||
kind: crate::ScalarKind::Bool,
|
||||
width: crate::BOOL_WIDTH,
|
||||
}
|
||||
&& types[members[1].ty].inner == crate::TypeInner::Scalar(crate::Scalar::BOOL)
|
||||
}
|
||||
|
@ -224,15 +224,11 @@ impl super::Validator {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) const fn check_width(
|
||||
&self,
|
||||
kind: crate::ScalarKind,
|
||||
width: crate::Bytes,
|
||||
) -> Result<(), WidthError> {
|
||||
let good = match kind {
|
||||
crate::ScalarKind::Bool => width == crate::BOOL_WIDTH,
|
||||
pub(super) const fn check_width(&self, scalar: crate::Scalar) -> Result<(), WidthError> {
|
||||
let good = match scalar.kind {
|
||||
crate::ScalarKind::Bool => scalar.width == crate::BOOL_WIDTH,
|
||||
crate::ScalarKind::Float => {
|
||||
if width == 8 {
|
||||
if scalar.width == 8 {
|
||||
if !self.capabilities.contains(Capabilities::FLOAT64) {
|
||||
return Err(WidthError::MissingCapability {
|
||||
name: "f64",
|
||||
@ -241,15 +237,15 @@ impl super::Validator {
|
||||
}
|
||||
true
|
||||
} else {
|
||||
width == 4
|
||||
scalar.width == 4
|
||||
}
|
||||
}
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => width == 4,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => scalar.width == 4,
|
||||
};
|
||||
if good {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(WidthError::Invalid(kind, width))
|
||||
Err(WidthError::Invalid(scalar.kind, scalar.width))
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,9 +262,9 @@ impl super::Validator {
|
||||
) -> Result<TypeInfo, TypeError> {
|
||||
use crate::TypeInner as Ti;
|
||||
Ok(match gctx.types[handle].inner {
|
||||
Ti::Scalar { kind, width } => {
|
||||
self.check_width(kind, width)?;
|
||||
let shareable = if kind.is_numeric() {
|
||||
Ti::Scalar(scalar) => {
|
||||
self.check_width(scalar)?;
|
||||
let shareable = if scalar.kind.is_numeric() {
|
||||
TypeFlags::IO_SHAREABLE | TypeFlags::HOST_SHAREABLE
|
||||
} else {
|
||||
TypeFlags::empty()
|
||||
@ -280,12 +276,12 @@ impl super::Validator {
|
||||
| TypeFlags::ARGUMENT
|
||||
| TypeFlags::CONSTRUCTIBLE
|
||||
| shareable,
|
||||
Alignment::from_width(width),
|
||||
Alignment::from_width(scalar.width),
|
||||
)
|
||||
}
|
||||
Ti::Vector { size, kind, width } => {
|
||||
self.check_width(kind, width)?;
|
||||
let shareable = if kind.is_numeric() {
|
||||
Ti::Vector { size, scalar } => {
|
||||
self.check_width(scalar)?;
|
||||
let shareable = if scalar.kind.is_numeric() {
|
||||
TypeFlags::IO_SHAREABLE | TypeFlags::HOST_SHAREABLE
|
||||
} else {
|
||||
TypeFlags::empty()
|
||||
@ -298,7 +294,7 @@ impl super::Validator {
|
||||
| TypeFlags::ARGUMENT
|
||||
| TypeFlags::CONSTRUCTIBLE
|
||||
| shareable,
|
||||
Alignment::from(size) * Alignment::from_width(width),
|
||||
Alignment::from(size) * Alignment::from_width(scalar.width),
|
||||
)
|
||||
}
|
||||
Ti::Matrix {
|
||||
@ -306,7 +302,7 @@ impl super::Validator {
|
||||
rows,
|
||||
width,
|
||||
} => {
|
||||
self.check_width(crate::ScalarKind::Float, width)?;
|
||||
self.check_width(crate::Scalar::float(width))?;
|
||||
TypeInfo::new(
|
||||
TypeFlags::DATA
|
||||
| TypeFlags::SIZED
|
||||
@ -317,7 +313,7 @@ impl super::Validator {
|
||||
Alignment::from(rows) * Alignment::from_width(width),
|
||||
)
|
||||
}
|
||||
Ti::Atomic { kind, width } => {
|
||||
Ti::Atomic(crate::Scalar { kind, width }) => {
|
||||
let good = match kind {
|
||||
crate::ScalarKind::Bool | crate::ScalarKind::Float => false,
|
||||
crate::ScalarKind::Sint | crate::ScalarKind::Uint => width == 4,
|
||||
@ -373,8 +369,7 @@ impl super::Validator {
|
||||
}
|
||||
Ti::ValuePointer {
|
||||
size: _,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
space,
|
||||
} => {
|
||||
// ValuePointer should be treated the same way as the equivalent
|
||||
@ -384,7 +379,7 @@ impl super::Validator {
|
||||
// However, some cases are trivial: All our implicit base types
|
||||
// are DATA and SIZED, so we can never return
|
||||
// `InvalidPointerBase` or `InvalidPointerToUnsized`.
|
||||
self.check_width(kind, width)?;
|
||||
self.check_width(scalar)?;
|
||||
|
||||
// `Validator::validate_function` actually checks the address
|
||||
// space of pointer arguments explicitly before checking the
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -47,10 +47,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -80,10 +80,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -92,10 +92,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Bool,
|
||||
width: 1,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -113,10 +113,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -134,10 +134,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -146,10 +146,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Bool,
|
||||
width: 1,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -167,10 +167,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -188,10 +188,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -218,10 +218,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -248,10 +248,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -334,10 +334,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -388,10 +388,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
|
@ -119,10 +119,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -131,10 +131,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Bool,
|
||||
width: 1,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -143,10 +143,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -155,10 +155,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -194,10 +194,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -226,8 +226,10 @@
|
||||
assignable_global: None,
|
||||
ty: Value(Vector(
|
||||
size: Bi,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
@ -246,10 +248,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -258,10 +260,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -270,10 +272,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -282,10 +284,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -303,10 +305,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -315,10 +317,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -345,10 +347,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -357,10 +359,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -378,10 +380,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -390,10 +392,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -402,10 +404,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
],
|
||||
sampling: [],
|
||||
@ -695,8 +697,10 @@
|
||||
assignable_global: Some(3),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
space: Uniform,
|
||||
)),
|
||||
),
|
||||
@ -707,10 +711,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -719,10 +723,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -731,10 +735,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Bool,
|
||||
width: 1,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -832,8 +836,10 @@
|
||||
assignable_global: None,
|
||||
ty: Value(Vector(
|
||||
size: Quad,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
@ -923,8 +929,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -937,10 +945,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1002,8 +1010,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -1016,10 +1026,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1081,8 +1091,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -1095,10 +1107,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1118,8 +1130,10 @@
|
||||
assignable_global: Some(5),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Private,
|
||||
)),
|
||||
),
|
||||
@ -1130,10 +1144,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1144,8 +1158,10 @@
|
||||
assignable_global: Some(5),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Private,
|
||||
)),
|
||||
),
|
||||
@ -1156,10 +1172,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1170,8 +1186,10 @@
|
||||
assignable_global: Some(5),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Private,
|
||||
)),
|
||||
),
|
||||
@ -1182,10 +1200,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1221,10 +1239,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1304,8 +1322,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -1318,10 +1338,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1383,8 +1403,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -1397,10 +1419,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1462,8 +1484,10 @@
|
||||
assignable_global: Some(4),
|
||||
ty: Value(ValuePointer(
|
||||
size: None,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
space: Storage(
|
||||
access: ("LOAD"),
|
||||
),
|
||||
@ -1476,10 +1500,10 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Value(Scalar(
|
||||
ty: Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@ -1643,81 +1667,81 @@
|
||||
),
|
||||
],
|
||||
const_expression_types: [
|
||||
Value(Scalar(
|
||||
Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
Handle(1),
|
||||
Handle(1),
|
||||
Handle(1),
|
||||
Handle(2),
|
||||
Value(Scalar(
|
||||
Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
Value(Scalar(
|
||||
))),
|
||||
Value(Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
)),
|
||||
))),
|
||||
],
|
||||
)
|
@ -2,25 +2,27 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: Some("GlobalConst"),
|
||||
@ -88,10 +90,10 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Atomic(
|
||||
inner: Atomic((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -105,8 +107,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -195,8 +199,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -231,10 +237,10 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -263,8 +269,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
|
@ -2,25 +2,27 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: Some("GlobalConst"),
|
||||
@ -88,10 +90,10 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Atomic(
|
||||
inner: Atomic((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -105,8 +107,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -195,16 +199,20 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -239,10 +247,10 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -271,8 +279,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -296,16 +306,20 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
|
@ -2,10 +2,10 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -33,8 +33,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -2,10 +2,10 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -33,8 +33,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
@ -2,40 +2,46 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -50,17 +56,19 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
|
@ -2,47 +2,53 @@
|
||||
types: [
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Tri,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Bool,
|
||||
width: 1,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
@ -63,10 +69,10 @@
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
inner: Scalar((
|
||||
kind: Sint,
|
||||
width: 4,
|
||||
),
|
||||
)),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
@ -86,8 +92,10 @@
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Quad,
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
scalar: (
|
||||
kind: Uint,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
|
@ -57,13 +57,18 @@ impl NumericDimension {
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NumericType {
|
||||
dim: NumericDimension,
|
||||
kind: naga::ScalarKind,
|
||||
width: naga::Bytes,
|
||||
scalar: naga::Scalar,
|
||||
}
|
||||
|
||||
impl fmt::Display for NumericType {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:?}{}{}", self.kind, self.width * 8, self.dim)
|
||||
write!(
|
||||
f,
|
||||
"{:?}{}{}",
|
||||
self.scalar.kind,
|
||||
self.scalar.width * 8,
|
||||
self.dim
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,77 +597,76 @@ impl Resource {
|
||||
|
||||
impl NumericType {
|
||||
fn from_vertex_format(format: wgt::VertexFormat) -> Self {
|
||||
use naga::{ScalarKind as Sk, VectorSize as Vs};
|
||||
use naga::{Scalar, VectorSize as Vs};
|
||||
use wgt::VertexFormat as Vf;
|
||||
|
||||
let (dim, kind, width) = match format {
|
||||
Vf::Uint32 => (NumericDimension::Scalar, Sk::Uint, 4),
|
||||
let (dim, scalar) = match format {
|
||||
Vf::Uint32 => (NumericDimension::Scalar, Scalar::U32),
|
||||
Vf::Uint8x2 | Vf::Uint16x2 | Vf::Uint32x2 => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Uint, 4)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::U32)
|
||||
}
|
||||
Vf::Uint32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Uint, 4),
|
||||
Vf::Uint32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::U32),
|
||||
Vf::Uint8x4 | Vf::Uint16x4 | Vf::Uint32x4 => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Uint, 4)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::U32)
|
||||
}
|
||||
Vf::Sint32 => (NumericDimension::Scalar, Sk::Sint, 4),
|
||||
Vf::Sint32 => (NumericDimension::Scalar, Scalar::I32),
|
||||
Vf::Sint8x2 | Vf::Sint16x2 | Vf::Sint32x2 => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Sint, 4)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::I32)
|
||||
}
|
||||
Vf::Sint32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Sint, 4),
|
||||
Vf::Sint32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::I32),
|
||||
Vf::Sint8x4 | Vf::Sint16x4 | Vf::Sint32x4 => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Sint, 4)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::I32)
|
||||
}
|
||||
Vf::Float32 => (NumericDimension::Scalar, Sk::Float, 4),
|
||||
Vf::Float32 => (NumericDimension::Scalar, Scalar::F32),
|
||||
Vf::Unorm8x2
|
||||
| Vf::Snorm8x2
|
||||
| Vf::Unorm16x2
|
||||
| Vf::Snorm16x2
|
||||
| Vf::Float16x2
|
||||
| Vf::Float32x2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 4),
|
||||
Vf::Float32x3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 4),
|
||||
| Vf::Float32x2 => (NumericDimension::Vector(Vs::Bi), Scalar::F32),
|
||||
Vf::Float32x3 => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Vf::Unorm8x4
|
||||
| Vf::Snorm8x4
|
||||
| Vf::Unorm16x4
|
||||
| Vf::Snorm16x4
|
||||
| Vf::Float16x4
|
||||
| Vf::Float32x4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 4),
|
||||
Vf::Float64 => (NumericDimension::Scalar, Sk::Float, 8),
|
||||
Vf::Float64x2 => (NumericDimension::Vector(Vs::Bi), Sk::Float, 8),
|
||||
Vf::Float64x3 => (NumericDimension::Vector(Vs::Tri), Sk::Float, 8),
|
||||
Vf::Float64x4 => (NumericDimension::Vector(Vs::Quad), Sk::Float, 8),
|
||||
| Vf::Float32x4 => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Vf::Float64 => (NumericDimension::Scalar, Scalar::F64),
|
||||
Vf::Float64x2 => (NumericDimension::Vector(Vs::Bi), Scalar::F64),
|
||||
Vf::Float64x3 => (NumericDimension::Vector(Vs::Tri), Scalar::F64),
|
||||
Vf::Float64x4 => (NumericDimension::Vector(Vs::Quad), Scalar::F64),
|
||||
};
|
||||
|
||||
NumericType {
|
||||
dim,
|
||||
kind,
|
||||
//Note: Shader always sees data as int, uint, or float.
|
||||
// It doesn't know if the original is normalized in a tighter form.
|
||||
width,
|
||||
scalar,
|
||||
}
|
||||
}
|
||||
|
||||
fn from_texture_format(format: wgt::TextureFormat) -> Self {
|
||||
use naga::{ScalarKind as Sk, VectorSize as Vs};
|
||||
use naga::{Scalar, VectorSize as Vs};
|
||||
use wgt::TextureFormat as Tf;
|
||||
|
||||
let (dim, kind) = match format {
|
||||
let (dim, scalar) = match format {
|
||||
Tf::R8Unorm | Tf::R8Snorm | Tf::R16Float | Tf::R32Float => {
|
||||
(NumericDimension::Scalar, Sk::Float)
|
||||
(NumericDimension::Scalar, Scalar::F32)
|
||||
}
|
||||
Tf::R8Uint | Tf::R16Uint | Tf::R32Uint => (NumericDimension::Scalar, Sk::Uint),
|
||||
Tf::R8Sint | Tf::R16Sint | Tf::R32Sint => (NumericDimension::Scalar, Sk::Sint),
|
||||
Tf::R8Uint | Tf::R16Uint | Tf::R32Uint => (NumericDimension::Scalar, Scalar::U32),
|
||||
Tf::R8Sint | Tf::R16Sint | Tf::R32Sint => (NumericDimension::Scalar, Scalar::I32),
|
||||
Tf::Rg8Unorm | Tf::Rg8Snorm | Tf::Rg16Float | Tf::Rg32Float => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::F32)
|
||||
}
|
||||
Tf::Rg8Uint | Tf::Rg16Uint | Tf::Rg32Uint => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Uint)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::U32)
|
||||
}
|
||||
Tf::Rg8Sint | Tf::Rg16Sint | Tf::Rg32Sint => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Sint)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::I32)
|
||||
}
|
||||
Tf::R16Snorm | Tf::R16Unorm => (NumericDimension::Scalar, Sk::Float),
|
||||
Tf::Rg16Snorm | Tf::Rg16Unorm => (NumericDimension::Vector(Vs::Bi), Sk::Float),
|
||||
Tf::Rgba16Snorm | Tf::Rgba16Unorm => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
Tf::R16Snorm | Tf::R16Unorm => (NumericDimension::Scalar, Scalar::F32),
|
||||
Tf::Rg16Snorm | Tf::Rg16Unorm => (NumericDimension::Vector(Vs::Bi), Scalar::F32),
|
||||
Tf::Rgba16Snorm | Tf::Rgba16Unorm => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Rgba8Unorm
|
||||
| Tf::Rgba8UnormSrgb
|
||||
| Tf::Rgba8Snorm
|
||||
@ -670,14 +674,14 @@ impl NumericType {
|
||||
| Tf::Bgra8UnormSrgb
|
||||
| Tf::Rgb10a2Unorm
|
||||
| Tf::Rgba16Float
|
||||
| Tf::Rgba32Float => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
| Tf::Rgba32Float => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Rgba8Uint | Tf::Rgba16Uint | Tf::Rgba32Uint | Tf::Rgb10a2Uint => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Uint)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::U32)
|
||||
}
|
||||
Tf::Rgba8Sint | Tf::Rgba16Sint | Tf::Rgba32Sint => {
|
||||
(NumericDimension::Vector(Vs::Quad), Sk::Sint)
|
||||
(NumericDimension::Vector(Vs::Quad), Scalar::I32)
|
||||
}
|
||||
Tf::Rg11b10Float => (NumericDimension::Vector(Vs::Tri), Sk::Float),
|
||||
Tf::Rg11b10Float => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Tf::Stencil8
|
||||
| Tf::Depth16Unorm
|
||||
| Tf::Depth32Float
|
||||
@ -686,7 +690,7 @@ impl NumericType {
|
||||
| Tf::Depth24PlusStencil8 => {
|
||||
panic!("Unexpected depth format")
|
||||
}
|
||||
Tf::Rgb9e5Ufloat => (NumericDimension::Vector(Vs::Tri), Sk::Float),
|
||||
Tf::Rgb9e5Ufloat => (NumericDimension::Vector(Vs::Tri), Scalar::F32),
|
||||
Tf::Bc1RgbaUnorm
|
||||
| Tf::Bc1RgbaUnormSrgb
|
||||
| Tf::Bc2RgbaUnorm
|
||||
@ -698,36 +702,35 @@ impl NumericType {
|
||||
| Tf::Etc2Rgb8A1Unorm
|
||||
| Tf::Etc2Rgb8A1UnormSrgb
|
||||
| Tf::Etc2Rgba8Unorm
|
||||
| Tf::Etc2Rgba8UnormSrgb => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
| Tf::Etc2Rgba8UnormSrgb => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
Tf::Bc4RUnorm | Tf::Bc4RSnorm | Tf::EacR11Unorm | Tf::EacR11Snorm => {
|
||||
(NumericDimension::Scalar, Sk::Float)
|
||||
(NumericDimension::Scalar, Scalar::F32)
|
||||
}
|
||||
Tf::Bc5RgUnorm | Tf::Bc5RgSnorm | Tf::EacRg11Unorm | Tf::EacRg11Snorm => {
|
||||
(NumericDimension::Vector(Vs::Bi), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Bi), Scalar::F32)
|
||||
}
|
||||
Tf::Bc6hRgbUfloat | Tf::Bc6hRgbFloat | Tf::Etc2Rgb8Unorm | Tf::Etc2Rgb8UnormSrgb => {
|
||||
(NumericDimension::Vector(Vs::Tri), Sk::Float)
|
||||
(NumericDimension::Vector(Vs::Tri), Scalar::F32)
|
||||
}
|
||||
Tf::Astc {
|
||||
block: _,
|
||||
channel: _,
|
||||
} => (NumericDimension::Vector(Vs::Quad), Sk::Float),
|
||||
} => (NumericDimension::Vector(Vs::Quad), Scalar::F32),
|
||||
};
|
||||
|
||||
NumericType {
|
||||
dim,
|
||||
kind,
|
||||
//Note: Shader always sees data as int, uint, or float.
|
||||
// It doesn't know if the original is normalized in a tighter form.
|
||||
width: 4,
|
||||
scalar,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_subtype_of(&self, other: &NumericType) -> bool {
|
||||
if self.width > other.width {
|
||||
if self.scalar.width > other.scalar.width {
|
||||
return false;
|
||||
}
|
||||
if self.kind != other.kind {
|
||||
if self.scalar.kind != other.scalar.kind {
|
||||
return false;
|
||||
}
|
||||
match (self.dim, other.dim) {
|
||||
@ -742,7 +745,7 @@ impl NumericType {
|
||||
}
|
||||
|
||||
fn is_compatible_with(&self, other: &NumericType) -> bool {
|
||||
if self.kind != other.kind {
|
||||
if self.scalar.kind != other.scalar.kind {
|
||||
return false;
|
||||
}
|
||||
match (self.dim, other.dim) {
|
||||
@ -778,15 +781,13 @@ impl Interface {
|
||||
arena: &naga::UniqueArena<naga::Type>,
|
||||
) {
|
||||
let numeric_ty = match arena[ty].inner {
|
||||
naga::TypeInner::Scalar { kind, width } => NumericType {
|
||||
naga::TypeInner::Scalar(scalar) => NumericType {
|
||||
dim: NumericDimension::Scalar,
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
naga::TypeInner::Vector { size, kind, width } => NumericType {
|
||||
naga::TypeInner::Vector { size, scalar } => NumericType {
|
||||
dim: NumericDimension::Vector(size),
|
||||
kind,
|
||||
width,
|
||||
scalar,
|
||||
},
|
||||
naga::TypeInner::Matrix {
|
||||
columns,
|
||||
@ -794,8 +795,7 @@ impl Interface {
|
||||
width,
|
||||
} => NumericType {
|
||||
dim: NumericDimension::Matrix(columns, rows),
|
||||
kind: naga::ScalarKind::Float,
|
||||
width,
|
||||
scalar: naga::Scalar::float(width),
|
||||
},
|
||||
naga::TypeInner::Struct { ref members, .. } => {
|
||||
for member in members {
|
||||
|
@ -1463,33 +1463,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Float 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Float,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::F32) => {
|
||||
let data = unsafe { get_data::<f32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_f32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_f32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_f32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Float,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::F32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<f32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_f32_slice(location, data) };
|
||||
@ -1498,33 +1492,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Int 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::I32) => {
|
||||
let data = unsafe { get_data::<i32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_i32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_i32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_i32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Sint,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::I32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<i32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_i32_slice(location, data) };
|
||||
@ -1533,33 +1521,27 @@ impl super::Queue {
|
||||
//
|
||||
// --- Uint 1-4 Component ---
|
||||
//
|
||||
naga::TypeInner::Scalar {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
width: 4,
|
||||
} => {
|
||||
naga::TypeInner::Scalar(naga::Scalar::U32) => {
|
||||
let data = unsafe { get_data::<u32, 1>(data_bytes, offset)[0] };
|
||||
unsafe { gl.uniform_1_u32(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Bi,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 2>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_2_u32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Tri,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 3>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_3_u32_slice(location, data) };
|
||||
}
|
||||
naga::TypeInner::Vector {
|
||||
kind: naga::ScalarKind::Uint,
|
||||
size: naga::VectorSize::Quad,
|
||||
width: 4,
|
||||
scalar: naga::Scalar::U32,
|
||||
} => {
|
||||
let data = unsafe { get_data::<u32, 4>(data_bytes, offset) };
|
||||
unsafe { gl.uniform_4_u32_slice(location, data) };
|
||||
|
Loading…
Reference in New Issue
Block a user