Skip to content

Commit

Permalink
[naga msl-out] Use Handle::write_prefixed instead of index.
Browse files Browse the repository at this point in the history
This replaces all uses of `Handle::index` for generating identifiers
in `naga::back::msl` with uses of `Handle::write_prefixed`.

There are still some uses of `Handle::index` remaining.
  • Loading branch information
jimblandy authored and teoxoy committed Jun 21, 2024
1 parent 29aa68e commit beb89f7
Showing 1 changed file with 53 additions and 22 deletions.
75 changes: 53 additions & 22 deletions naga/src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,39 @@ const fn scalar_is_int(scalar: crate::Scalar) -> bool {
/// Prefix for cached clamped level-of-detail values for `ImageLoad` expressions.
const CLAMPED_LOD_LOAD_PREFIX: &str = "clamped_lod_e";

/// Wrapper for identifier names for clamped level-of-detail values
///
/// Values of this type implement [`std::fmt::Display`], formatting as
/// the name of the variable used to hold the cached clamped
/// level-of-detail value for an `ImageLoad` expression.
struct ClampedLod(Handle<crate::Expression>);

impl Display for ClampedLod {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.0.write_prefixed(f, CLAMPED_LOD_LOAD_PREFIX)
}
}

/// Wrapper for generating `struct _mslBufferSizes` member names for
/// runtime-sized array lengths.
///
/// On Metal, `wgpu_hal` passes the element counts for all runtime-sized arrays
/// as an argument to the entry point. This argument's type in the MSL is
/// `struct _mslBufferSizes`, a Naga-synthesized struct with a `uint` member for
/// each global variable containing a runtime-sized array.
///
/// If `global` is a [`Handle`] for a [`GlobalVariable`] that contains a
/// runtime-sized array, then the value `ArraySize(global)` implements
/// [`std::fmt::Display`], formatting as the name of the struct member carrying
/// the number of elements in that runtime-sized array.
struct ArraySizeMember(Handle<crate::GlobalVariable>);

impl Display for ArraySizeMember {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
self.0.write_prefixed(f, "size")
}
}

struct TypeContext<'a> {
handle: Handle<crate::Type>,
gctx: proc::GlobalCtx<'a>,
Expand Down Expand Up @@ -677,9 +710,7 @@ impl<W: Write> Writer<W> {
) -> BackendResult {
match level {
LevelOfDetail::Direct(expr) => self.put_expression(expr, context, true)?,
LevelOfDetail::Restricted(load) => {
write!(self.out, "{}{}", CLAMPED_LOD_LOAD_PREFIX, load.index())?
}
LevelOfDetail::Restricted(load) => write!(self.out, "{}", ClampedLod(load))?,
}
Ok(())
}
Expand Down Expand Up @@ -1146,8 +1177,8 @@ impl<W: Write> Writer<W> {
// prevent that.
write!(
self.out,
"(_buffer_sizes.size{idx} - {offset} - {size}) / {stride}",
idx = handle.index(),
"(_buffer_sizes.{member} - {offset} - {size}) / {stride}",
member = ArraySizeMember(handle),
offset = offset,
size = size,
stride = stride,
Expand Down Expand Up @@ -2778,13 +2809,7 @@ impl<W: Write> Writer<W> {
return Ok(());
}

write!(
self.out,
"{}uint {}{} = ",
indent,
CLAMPED_LOD_LOAD_PREFIX,
load.index(),
)?;
write!(self.out, "{}uint {} = ", indent, ClampedLod(load),)?;
self.put_restricted_scalar_image_index(
image,
level_of_detail,
Expand Down Expand Up @@ -3444,24 +3469,30 @@ impl<W: Write> Writer<W> {
writeln!(self.out)?;

{
let mut indices = vec![];
for (handle, var) in module.global_variables.iter() {
if needs_array_length(var.ty, &module.types) {
let idx = handle.index();
indices.push(idx);
}
}
// Make a `Vec` of all the `GlobalVariable`s that contain
// runtime-sized arrays.
let globals: Vec<Handle<crate::GlobalVariable>> = module
.global_variables
.iter()
.filter(|&(_, var)| needs_array_length(var.ty, &module.types))
.map(|(handle, _)| handle)
.collect();

let mut buffer_indices = vec![];
for vbm in &pipeline_options.vertex_buffer_mappings {
buffer_indices.push(vbm.id);
}

if !indices.is_empty() || !buffer_indices.is_empty() {
if !globals.is_empty() || !buffer_indices.is_empty() {
writeln!(self.out, "struct _mslBufferSizes {{")?;

for idx in indices {
writeln!(self.out, "{}uint size{};", back::INDENT, idx)?;
for global in globals {
writeln!(
self.out,
"{}uint {};",
back::INDENT,
ArraySizeMember(global)
)?;
}

for idx in buffer_indices {
Expand Down

0 comments on commit beb89f7

Please sign in to comment.