mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
[spv-in] Handle structs with no offset decorations
This commit is contained in:
committed by
Dzmitry Malyshau
parent
4fa280d931
commit
803093e710
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -127,3 +127,20 @@ impl ops::Index<Handle<crate::Expression>> 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)
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ use function::*;
|
||||
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
proc::{Alignment, Layouter},
|
||||
proc::Layouter,
|
||||
FastHashMap,
|
||||
};
|
||||
|
||||
@@ -3245,10 +3245,11 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
.update(&module.types, &module.constants)
|
||||
.unwrap();
|
||||
|
||||
let mut struct_alignment = Alignment::new(1).unwrap();
|
||||
let mut members = Vec::<crate::StructMember>::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<I: Iterator<Item = u32>> Parser<I> {
|
||||
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<I: Iterator<Item = u32>> Parser<I> {
|
||||
}
|
||||
}
|
||||
|
||||
struct_alignment = struct_alignment.max(self.layouter[ty].alignment);
|
||||
|
||||
members.push(crate::StructMember {
|
||||
name: decor.name,
|
||||
ty,
|
||||
@@ -3302,16 +3308,11 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
});
|
||||
}
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user