diff --git a/src/front/glsl/offset.rs b/src/front/glsl/offset.rs index 2c2140b932..2d4f238dac 100644 --- a/src/front/glsl/offset.rs +++ b/src/front/glsl/offset.rs @@ -13,7 +13,7 @@ use super::{ error::{Error, ErrorKind}, SourceMetadata, }; -use crate::{Arena, Constant, Handle, Type, TypeInner}; +use crate::{front::align_up, Arena, Constant, Handle, Type, TypeInner}; /// Struct with information needed for defining a struct member. /// @@ -170,20 +170,3 @@ pub fn calculate_offset( TypeAlignSpan { ty, align, span } } - -/// Helper function used for aligning `value` to the next multiple of `align` -/// -/// # Notes: -/// - `align` must be a power of two. -/// - The returned value will be greater or equal to `value`. -/// # Examples: -/// ```ignore -/// assert_eq!(0, align_up(0, 16)); -/// assert_eq!(16, align_up(1, 16)); -/// assert_eq!(16, align_up(16, 16)); -/// assert_eq!(334, align_up(333, 2)); -/// assert_eq!(384, align_up(257, 128)); -/// ``` -pub fn align_up(value: u32, align: u32) -> u32 { - ((value.wrapping_sub(1)) & !(align - 1)).wrapping_add(align) -} diff --git a/src/front/glsl/parser/declarations.rs b/src/front/glsl/parser/declarations.rs index 546c366a29..53e1687d2c 100644 --- a/src/front/glsl/parser/declarations.rs +++ b/src/front/glsl/parser/declarations.rs @@ -597,7 +597,7 @@ impl<'source> ParsingContext<'source> { &mut parser.errors, ); - span = offset::align_up(span, info.align); + span = crate::front::align_up(span, info.align); align = align.max(info.align); members.push(StructMember { @@ -614,7 +614,7 @@ impl<'source> ParsingContext<'source> { } } - span = offset::align_up(span, align); + span = crate::front::align_up(span, align); Ok(span) } diff --git a/src/front/mod.rs b/src/front/mod.rs index c9d71d2987..8c7b03a7ea 100644 --- a/src/front/mod.rs +++ b/src/front/mod.rs @@ -127,3 +127,20 @@ impl ops::Index> for Typifier { &self.resolutions[handle.index()] } } + +/// Helper function used for aligning `value` to the next multiple of `align` +/// +/// # Notes: +/// - `align` must be a power of two. +/// - The returned value will be greater or equal to `value`. +/// # Examples: +/// ```ignore +/// assert_eq!(0, align_up(0, 16)); +/// assert_eq!(16, align_up(1, 16)); +/// assert_eq!(16, align_up(16, 16)); +/// assert_eq!(334, align_up(333, 2)); +/// assert_eq!(384, align_up(257, 128)); +/// ``` +pub fn align_up(value: u32, align: u32) -> u32 { + ((value.wrapping_sub(1)) & !(align - 1)).wrapping_add(align) +} diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index 35646e059b..60191d2cba 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -40,7 +40,7 @@ use function::*; use crate::{ arena::{Arena, Handle}, - proc::{Alignment, Layouter}, + proc::Layouter, FastHashMap, }; @@ -3245,10 +3245,11 @@ impl> Parser { .update(&module.types, &module.constants) .unwrap(); - let mut struct_alignment = Alignment::new(1).unwrap(); let mut members = Vec::::with_capacity(inst.wc as usize - 2); let mut member_lookups = Vec::with_capacity(members.capacity()); let mut storage_access = crate::StorageAccess::empty(); + let mut span = 0; + let mut alignment = 1; for i in 0..u32::from(inst.wc) - 2 { let type_id = self.next()?; let ty = self.lookup_type.lookup(type_id)?.handle; @@ -3264,9 +3265,16 @@ impl> Parser { row_major: decor.matrix_major == Some(Majority::Row), }); + span = crate::front::align_up(span, self.layouter[ty].alignment.get()); + alignment = self.layouter[ty].alignment.get().max(alignment); + let binding = decor.io_binding().ok(); - // I/O structs don't have to have offsets, others do - let offset = decor.offset.unwrap_or(0); + if let Some(offset) = decor.offset { + span = offset; + } + let offset = span; + + span += self.layouter[ty].size; if let crate::TypeInner::Matrix { columns, @@ -3292,8 +3300,6 @@ impl> Parser { } } - struct_alignment = struct_alignment.max(self.layouter[ty].alignment); - members.push(crate::StructMember { name: decor.name, ty, @@ -3302,16 +3308,11 @@ impl> Parser { }); } + span = crate::front::align_up(span, alignment); + let inner = crate::TypeInner::Struct { top_level: block_decor.is_some(), - span: members - .iter() - .map(|member| { - let end = member.offset + module.types[member.ty].inner.span(&module.constants); - ((end - 1) | (struct_alignment.get() - 1)) + 1 - }) - .max() - .unwrap_or(4), //do we support this? + span, members, };