Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 27 additions & 15 deletions naga/src/back/hlsl/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ pub(super) struct WrappedStructMatrixAccess {
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub(super) struct WrappedMatCx2 {
pub(super) columns: crate::VectorSize,
pub(super) width: u8,
}

#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
Expand Down Expand Up @@ -838,13 +839,17 @@ impl<W: Write> super::Writer<'_, W> {
if let Some(super::writer::MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = super::writer::get_inner_matrix_data(module, member.ty)
{
write!(
self.out,
"{}{}.{} = (__mat{}x2",
INDENT, RETURN_VARIABLE_NAME, field_name, columns as u8
"{}{}.{} = (__mat{}x2_f{}",
INDENT,
RETURN_VARIABLE_NAME,
field_name,
columns as u8,
width * 8
)?;
if let crate::TypeInner::Array { base, size, .. } = *other {
self.write_array_size(module, base, size)?;
Expand Down Expand Up @@ -2141,35 +2146,42 @@ impl<W: Write> super::Writer<'_, W> {

pub(super) fn write_mat_cx2_typedef_and_functions(
&mut self,
WrappedMatCx2 { columns }: WrappedMatCx2,
WrappedMatCx2 { columns, width }: WrappedMatCx2,
) -> BackendResult {
use crate::back::INDENT;

let bit_width = width * 8;
let type_name = crate::Scalar {
kind: ScalarKind::Float,
width,
}
.to_hlsl_str()?;

// typedef
write!(self.out, "typedef struct {{ ")?;
for i in 0..columns as u8 {
write!(self.out, "float2 _{i}; ")?;
write!(self.out, "{type_name}2 _{i}; ")?;
}
writeln!(self.out, "}} __mat{}x2;", columns as u8)?;
writeln!(self.out, "}} __mat{}x2_f{bit_width};", columns as u8)?;

// __get_col_of_mat
writeln!(
self.out,
"float2 __get_col_of_mat{}x2(__mat{}x2 mat, uint idx) {{",
"{type_name}2 __get_col_of_mat{}x2_f{bit_width}(__mat{}x2_f{bit_width} mat, uint idx) {{",
columns as u8, columns as u8
)?;
writeln!(self.out, "{INDENT}switch(idx) {{")?;
for i in 0..columns as u8 {
writeln!(self.out, "{INDENT}case {i}: {{ return mat._{i}; }}")?;
}
writeln!(self.out, "{INDENT}default: {{ return (float2)0; }}")?;
writeln!(self.out, "{INDENT}default: {{ return ({type_name}2)0; }}")?;
writeln!(self.out, "{INDENT}}}")?;
writeln!(self.out, "}}")?;

// __set_col_of_mat
writeln!(
self.out,
"void __set_col_of_mat{}x2(__mat{}x2 mat, uint idx, float2 value) {{",
"void __set_col_of_mat{}x2_f{bit_width}(__mat{}x2_f{bit_width} mat, uint idx, {type_name}2 value) {{",
columns as u8, columns as u8
)?;
writeln!(self.out, "{INDENT}switch(idx) {{")?;
Expand All @@ -2182,7 +2194,7 @@ impl<W: Write> super::Writer<'_, W> {
// __set_el_of_mat
writeln!(
self.out,
"void __set_el_of_mat{}x2(__mat{}x2 mat, uint idx, uint vec_idx, float value) {{",
"void __set_el_of_mat{}x2_f{bit_width}(__mat{}x2_f{bit_width} mat, uint idx, uint vec_idx, {type_name} value) {{",
columns as u8, columns as u8
)?;
writeln!(self.out, "{INDENT}switch(idx) {{")?;
Expand Down Expand Up @@ -2211,10 +2223,10 @@ impl<W: Write> super::Writer<'_, W> {
if let Some(super::writer::MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = super::writer::get_inner_matrix_data(module, global.ty)
{
let entry = WrappedMatCx2 { columns };
let entry = WrappedMatCx2 { columns, width };
if self.wrapped.insert(WrappedType::MatCx2(entry)) {
self.write_mat_cx2_typedef_and_functions(entry)?;
}
Expand All @@ -2229,10 +2241,10 @@ impl<W: Write> super::Writer<'_, W> {
if let Some(super::writer::MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = super::writer::get_inner_matrix_data(module, member.ty)
{
let entry = WrappedMatCx2 { columns };
let entry = WrappedMatCx2 { columns, width };
if self.wrapped.insert(WrappedType::MatCx2(entry)) {
self.write_mat_cx2_typedef_and_functions(entry)?;
}
Expand Down Expand Up @@ -2267,7 +2279,7 @@ impl<W: Write> super::Writer<'_, W> {
///
/// ```text
/// tests\out\hlsl\access.hlsl:183:41: error: cannot compile this l-value expression yet
/// t_1.am = (__mat4x2[2])((float4x2[2])0);
/// t_1.am = (__mat4x2_f32[2])((float4x2[2])0);
/// ^
/// ```
fn write_wrapped_zero_value_function(
Expand Down
97 changes: 47 additions & 50 deletions naga/src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1519,10 +1519,10 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if let Some(MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = matrix_data
{
write!(self.out, "__mat{}x2", columns as u8)?;
write!(self.out, "__mat{}x2_f{}", columns as u8, width * 8)?;
} else {
// Even though Naga IR matrices are column-major, we must describe
// matrices passed from the CPU as being in row-major order.
Expand Down Expand Up @@ -2380,6 +2380,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
},
Struct {
columns: crate::VectorSize,
width: u8,
base: Handle<crate::Expression>,
},
}
Expand Down Expand Up @@ -2422,7 +2423,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if let Some(MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = get_inner_matrix_of_struct_array_member(
module,
matrix_expr,
Expand All @@ -2432,6 +2433,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
Some((
MatrixAccess::Struct {
columns,
width,
base: matrix_expr,
},
vector,
Expand Down Expand Up @@ -2507,17 +2509,31 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
}
}
Some((
MatrixAccess::Struct { columns, base },
MatrixAccess::Struct {
columns,
width,
base,
},
Some(Index::Expression(vec_index)),
scalar,
)) => {
// We handle `Store`s to __matCx2 column vectors and scalar elements via
// the previously injected functions __set_col_of_matCx2 / __set_el_of_matCx2.

if scalar.is_some() {
write!(self.out, "__set_el_of_mat{}x2", columns as u8)?;
write!(
self.out,
"__set_el_of_mat{}x2_f{}",
columns as u8,
width * 8
)?;
} else {
write!(self.out, "__set_col_of_mat{}x2", columns as u8)?;
write!(
self.out,
"__set_col_of_mat{}x2_f{}",
columns as u8,
width * 8
)?;
}
write!(self.out, "(")?;
self.write_expr(module, base, func_ctx)?;
Expand Down Expand Up @@ -2547,7 +2563,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if let Some(MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = get_inner_matrix_of_struct_array_member(
module, pointer, func_ctx, false,
) {
Expand All @@ -2556,7 +2572,7 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
resolved = &module.types[base].inner;
}

write!(self.out, "(__mat{}x2", columns as u8)?;
write!(self.out, "(__mat{}x2_f{}", columns as u8, width * 8)?;
if let TypeInner::Array { base, size, .. } = *resolved {
self.write_array_size(module, base, size)?;
}
Expand Down Expand Up @@ -3336,11 +3352,18 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
if let Some(MatrixType {
columns,
rows: crate::VectorSize::Bi,
width: 4,
width,
}) = get_inner_matrix_of_struct_array_member(module, base, func_ctx, true)
.or_else(|| get_global_uniform_matrix(module, base, func_ctx))
.or_else(|| {
get_inner_matrix_of_global_uniform(module, base, func_ctx, true)
})
{
write!(self.out, "__get_col_of_mat{}x2(", columns as u8)?;
write!(
self.out,
"__get_col_of_mat{}x2_f{}(",
columns as u8,
width * 8
)?;
self.write_expr(module, base, func_ctx)?;
write!(self.out, ", ")?;
self.write_expr(module, index, func_ctx)?;
Expand Down Expand Up @@ -3459,10 +3482,11 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
// __matCx2 struct.
if let Some(MatrixType {
rows: crate::VectorSize::Bi,
width: 4,
..
}) = get_inner_matrix_of_struct_array_member(module, base, func_ctx, true)
.or_else(|| get_global_uniform_matrix(module, base, func_ctx))
.or_else(|| {
get_inner_matrix_of_global_uniform(module, base, func_ctx, true)
})
{
self.write_expr(module, base, func_ctx)?;
write!(self.out, "._{index}")?;
Expand Down Expand Up @@ -3806,13 +3830,13 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
// - a (possibly nested) array of __matCx2's
if let Some(MatrixType {
rows: crate::VectorSize::Bi,
width: 4,
..
}) = get_inner_matrix_of_struct_array_member(
module, pointer, func_ctx, false,
)
.or_else(|| get_inner_matrix_of_global_uniform(module, pointer, func_ctx))
{
.or_else(|| {
get_inner_matrix_of_global_uniform(module, pointer, func_ctx, false)
}) {
let mut resolved = func_ctx.resolve_type(pointer, &module.types);
let ptr_tr = resolved.pointer_base_type();
if let Some(ptr_ty) =
Expand Down Expand Up @@ -5018,44 +5042,15 @@ pub(super) fn get_inner_matrix_of_struct_array_member(
None
}

/// Simpler version of get_inner_matrix_of_global_uniform that only looks at the
/// immediate expression, rather than traversing an access chain.
fn get_global_uniform_matrix(
module: &Module,
base: Handle<crate::Expression>,
func_ctx: &back::FunctionCtx<'_>,
) -> Option<MatrixType> {
let base_tr = func_ctx
.resolve_type(base, &module.types)
.pointer_base_type();
let base_ty = base_tr.as_ref().map(|tr| tr.inner_with(&module.types));
match (&func_ctx.expressions[base], base_ty) {
(
&crate::Expression::GlobalVariable(handle),
Some(&TypeInner::Matrix {
columns,
rows,
scalar,
}),
) if module.global_variables[handle].space == crate::AddressSpace::Uniform => {
Some(MatrixType {
columns,
rows,
width: scalar.width,
})
}
_ => None,
}
}

/// Returns the matrix data if the access chain starting at `base`:
/// - starts with an expression with resolved type of [`TypeInner::Matrix`]
/// - contains zero or more expressions with resolved type of [`TypeInner::Array`] of [`TypeInner::Matrix`]
/// - ends with an [`Expression::GlobalVariable`](crate::Expression::GlobalVariable) in [`AddressSpace::Uniform`](crate::AddressSpace::Uniform)
/// - starts with an expression with resolved type of [`TypeInner::Matrix`], or
/// - contains zero or more expressions with resolved type of [`TypeInner::Array`] of [`TypeInner::Matrix`] if `direct = false`
/// - and ends with an [`Expression::GlobalVariable`](crate::Expression::GlobalVariable) in [`AddressSpace::Uniform`](crate::AddressSpace::Uniform)
fn get_inner_matrix_of_global_uniform(
module: &Module,
base: Handle<crate::Expression>,
func_ctx: &back::FunctionCtx<'_>,
direct: bool,
) -> Option<MatrixType> {
let mut mat_data = None;
let mut array_base = None;
Expand All @@ -5080,7 +5075,9 @@ fn get_inner_matrix_of_global_uniform(
})
}
TypeInner::Array { base, .. } => {
array_base = Some(base);
if !direct {
array_base = Some(base);
}
}
_ => break,
}
Expand Down
Loading
Loading