Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

[hlsl-out] Add more padding when necessary #1814

Merged
merged 7 commits into from
Apr 12, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
47 changes: 33 additions & 14 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,11 @@ impl<'a, W: Write> Writer<'a, W> {
self.collect_reflection_info()
}

fn write_array_size(&mut self, size: crate::ArraySize) -> BackendResult {
fn write_array_size(
&mut self,
base: Handle<crate::Type>,
size: crate::ArraySize,
) -> BackendResult {
write!(self.out, "[")?;

// Write the array size
Expand All @@ -751,6 +755,16 @@ impl<'a, W: Write> Writer<'a, W> {
}

write!(self.out, "]")?;

if let TypeInner::Array {
base: next_base,
size: next_size,
..
} = self.module.types[base].inner
{
self.write_array_size(next_base, next_size)?;
}

Ok(())
}

Expand Down Expand Up @@ -807,7 +821,7 @@ impl<'a, W: Write> Writer<'a, W> {
// GLSL arrays are written as `type name[size]`
// Current code is written arrays only as `[size]`
// Base `type` and `name` should be written outside
TypeInner::Array { size, .. } => self.write_array_size(size)?,
TypeInner::Array { base, size, .. } => self.write_array_size(base, size)?,
// Panic if either Image, Sampler, Pointer, or a Struct is being written
//
// Write all variants instead of `_` so that if new variants are added a
Expand Down Expand Up @@ -994,8 +1008,8 @@ impl<'a, W: Write> Writer<'a, W> {
write!(self.out, " ")?;
self.write_global_name(handle, global)?;

if let TypeInner::Array { size, .. } = self.module.types[global.ty].inner {
self.write_array_size(size)?;
if let TypeInner::Array { base, size, .. } = self.module.types[global.ty].inner {
self.write_array_size(base, size)?;
}

if global.space.initializable() && is_value_init_supported(self.module, global.ty) {
Expand Down Expand Up @@ -1298,6 +1312,11 @@ impl<'a, W: Write> Writer<'a, W> {
// The leading space is important
write!(this.out, " {}", &this.names[&ctx.argument_key(i as u32)])?;

// Write array size
if let TypeInner::Array { base, size, .. } = this.module.types[arg.ty].inner {
this.write_array_size(base, size)?;
}

Ok(())
})?;

Expand Down Expand Up @@ -1356,8 +1375,8 @@ impl<'a, W: Write> Writer<'a, W> {
// The leading space is important
write!(self.out, " {}", self.names[&ctx.name_key(handle)])?;
// Write size for array type
if let TypeInner::Array { size, .. } = self.module.types[local.ty].inner {
self.write_array_size(size)?;
if let TypeInner::Array { base, size, .. } = self.module.types[local.ty].inner {
self.write_array_size(base, size)?;
}
// Write the local initializer if needed
if let Some(init) = local.init {
Expand Down Expand Up @@ -1448,8 +1467,8 @@ impl<'a, W: Write> Writer<'a, W> {
// `type(components)` where `components` is a comma separated list of constants
crate::ConstantInner::Composite { ty, ref components } => {
self.write_type(ty)?;
if let TypeInner::Array { size, .. } = self.module.types[ty].inner {
self.write_array_size(size)?;
if let TypeInner::Array { base, size, .. } = self.module.types[ty].inner {
self.write_array_size(base, size)?;
}
write!(self.out, "(")?;

Expand Down Expand Up @@ -1525,7 +1544,7 @@ impl<'a, W: Write> Writer<'a, W> {
&self.names[&NameKey::StructMember(handle, idx as u32)]
)?;
// Write [size]
self.write_array_size(size)?;
self.write_array_size(base, size)?;
// Newline is important
writeln!(self.out, ";")?;
}
Expand Down Expand Up @@ -2056,8 +2075,8 @@ impl<'a, W: Write> Writer<'a, W> {
self.write_type(ty)?;

let resolved = ctx.info[expr].ty.inner_with(&self.module.types);
if let TypeInner::Array { size, .. } = *resolved {
self.write_array_size(size)?;
if let TypeInner::Array { base, size, .. } = *resolved {
self.write_array_size(base, size)?;
}

write!(self.out, "(")?;
Expand Down Expand Up @@ -2909,8 +2928,8 @@ impl<'a, W: Write> Writer<'a, W> {
let resolved = base_ty_res.inner_with(&self.module.types);

write!(self.out, " {}", name)?;
if let TypeInner::Array { size, .. } = *resolved {
self.write_array_size(size)?;
if let TypeInner::Array { base, size, .. } = *resolved {
self.write_array_size(base, size)?;
}
write!(self.out, " = ")?;
self.write_expr(handle, ctx)?;
Expand Down Expand Up @@ -2948,7 +2967,7 @@ impl<'a, W: Write> Writer<'a, W> {
proc::IndexableLength::Dynamic => return Ok(()),
};
self.write_type(base)?;
self.write_array_size(size)?;
self.write_array_size(base, size)?;
write!(self.out, "(")?;
for _ in 1..count {
self.write_zero_init_value(base)?;
Expand Down
75 changes: 75 additions & 0 deletions src/back/hlsl/conv.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::borrow::Cow;

use super::Error;

impl crate::ScalarKind {
Expand Down Expand Up @@ -35,6 +37,79 @@ impl crate::TypeInner {
_ => false,
}
}

pub(super) fn try_size_hlsl(
&self,
types: &crate::UniqueArena<crate::Type>,
constants: &crate::Arena<crate::Constant>,
) -> Result<u32, crate::arena::BadHandle> {
Ok(match *self {
Self::Matrix {
columns,
rows,
width,
} => {
let aligned_rows = if rows > crate::VectorSize::Bi { 4 } else { 2 };
let stride = aligned_rows * width as u32;
let last_row_size = rows as u32 * width as u32;
((columns as u32 - 1) * stride) + last_row_size
}
Self::Array { base, size, stride } => {
let count = match size {
crate::ArraySize::Constant(handle) => {
let constant = constants.try_get(handle)?;
constant.to_array_length().unwrap_or(1)
}
// A dynamically-sized array has to have at least one element
crate::ArraySize::Dynamic => 1,
};
let last_el_size = types[base].inner.try_size_hlsl(types, constants)?;
((count - 1) * stride) + last_el_size
}
_ => self.try_size(constants)?,
})
}

/// Used to generate the name of the wrapped type constructor
pub(super) fn hlsl_type_id<'a>(
&self,
base: crate::Handle<crate::Type>,
types: &crate::UniqueArena<crate::Type>,
constants: &crate::Arena<crate::Constant>,
names: &'a crate::FastHashMap<crate::proc::NameKey, String>,
) -> Result<Cow<'a, str>, Error> {
Ok(match types[base].inner {
crate::TypeInner::Scalar { kind, width } => Cow::Borrowed(kind.to_hlsl_str(width)?),
crate::TypeInner::Vector { size, kind, width } => Cow::Owned(format!(
"{}{}",
kind.to_hlsl_str(width)?,
crate::back::vector_size_str(size)
)),
crate::TypeInner::Matrix {
columns,
rows,
width,
} => Cow::Owned(format!(
"{}{}x{}",
crate::ScalarKind::Float.to_hlsl_str(width)?,
crate::back::vector_size_str(columns),
crate::back::vector_size_str(rows),
)),
crate::TypeInner::Array {
base,
size: crate::ArraySize::Constant(size),
..
} => Cow::Owned(format!(
"array{}_{}_",
constants[size].to_array_length().unwrap(),
self.hlsl_type_id(base, types, constants, names)?
)),
crate::TypeInner::Struct { .. } => {
Cow::Borrowed(&names[&crate::proc::NameKey::Type(base)])
}
_ => unreachable!(),
})
}
}

impl crate::StorageFormat {
Expand Down
Loading