mirror of
https://github.com/gfx-rs/wgpu.git
synced 2026-04-22 03:02:01 -04:00
Use UniqueArena for types.
Ensure that each distinct type occurs only once in `Module::types`, so that we can use `Eq` on `Type` or `TypeInner` for type equivalence, without being confused by differing `Handle<Type>` values that point to identical types. This removes a number of duplicate types from the ir snapshots. Fixes #1385.
This commit is contained in:
committed by
Dzmitry Malyshau
parent
d026577a91
commit
944a693ae5
@@ -20,6 +20,7 @@ bitflags = "1"
|
||||
bit-set = "0.5"
|
||||
codespan-reporting = { version = "0.11.0", optional = true }
|
||||
fxhash = "0.2"
|
||||
indexmap = "1.6" # 1.7 has MSRV 1.49
|
||||
log = "0.4"
|
||||
num-traits = "0.2"
|
||||
spirv = { version = "0.2", optional = true }
|
||||
@@ -36,8 +37,8 @@ glsl-in = ["pp-rs"]
|
||||
glsl-validate = []
|
||||
glsl-out = ["petgraph"]
|
||||
msl-out = []
|
||||
serialize = ["serde"]
|
||||
deserialize = ["serde"]
|
||||
serialize = ["serde", "indexmap/serde-1"]
|
||||
deserialize = ["serde", "indexmap/serde-1"]
|
||||
spv-in = ["petgraph", "spirv"]
|
||||
spv-out = ["spirv"]
|
||||
wgsl-in = ["codespan-reporting", "hexf-parse"]
|
||||
|
||||
195
src/arena.rs
195
src/arena.rs
@@ -6,8 +6,11 @@ use std::{cmp::Ordering, fmt, hash, marker::PhantomData, num::NonZeroU32, ops};
|
||||
type Index = NonZeroU32;
|
||||
|
||||
use crate::Span;
|
||||
use indexmap::set::IndexSet;
|
||||
|
||||
/// A strongly typed reference to an arena item.
|
||||
///
|
||||
/// A `Handle` value can be used as an index into an [`Arena`] or [`UniqueArena`].
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(serde::Deserialize))]
|
||||
#[cfg_attr(
|
||||
@@ -81,7 +84,8 @@ impl<T> Handle<T> {
|
||||
use std::convert::TryFrom;
|
||||
|
||||
let handle_index = u32::try_from(index + 1)
|
||||
.and_then(Index::try_from)
|
||||
.ok()
|
||||
.and_then(Index::new)
|
||||
.expect("Failed to insert into UniqueArena. Handle overflows");
|
||||
Handle::new(handle_index)
|
||||
}
|
||||
@@ -369,3 +373,192 @@ mod tests {
|
||||
assert!(arena[t1] != arena[t2]);
|
||||
}
|
||||
}
|
||||
|
||||
/// An arena whose elements are guaranteed to be unique.
|
||||
///
|
||||
/// A `UniqueArena` holds a set of unique values of type `T`, each with an
|
||||
/// associated [`Span`]. Inserting a value returns a `Handle<T>`, which can be
|
||||
/// used to index the `UniqueArena` and obtain shared access to the `T` element.
|
||||
/// Access via a `Handle` is an array lookup - no hash lookup is necessary.
|
||||
///
|
||||
/// The element type must implement `Eq` and `Hash`. Insertions of equivalent
|
||||
/// elements, according to `Eq`, all return the same `Handle`.
|
||||
///
|
||||
/// Once inserted, elements may not be mutated.
|
||||
///
|
||||
/// `UniqueArena` is similar to [`Arena`]: If `Arena` is vector-like,
|
||||
/// `UniqueArena` is `HashSet`-like.
|
||||
pub struct UniqueArena<T> {
|
||||
set: IndexSet<T>,
|
||||
|
||||
/// Spans for the elements, indexed by handle.
|
||||
///
|
||||
/// The length of this vector is always equal to `set.len()`. `IndexSet`
|
||||
/// promises that its elements "are indexed in a compact range, without
|
||||
/// holes in the range 0..set.len()", so we can always use the indices
|
||||
/// returned by insertion as indices into this vector.
|
||||
#[cfg(feature = "span")]
|
||||
span_info: Vec<Span>,
|
||||
}
|
||||
|
||||
impl<T> UniqueArena<T> {
|
||||
/// Create a new arena with no initial capacity allocated.
|
||||
pub fn new() -> Self {
|
||||
UniqueArena {
|
||||
set: IndexSet::new(),
|
||||
#[cfg(feature = "span")]
|
||||
span_info: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the current number of items stored in this arena.
|
||||
pub fn len(&self) -> usize {
|
||||
self.set.len()
|
||||
}
|
||||
|
||||
/// Return `true` if the arena contains no elements.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.set.is_empty()
|
||||
}
|
||||
|
||||
/// Clears the arena, keeping all allocations.
|
||||
pub fn clear(&mut self) {
|
||||
self.set.clear();
|
||||
#[cfg(feature = "span")]
|
||||
self.span_info.clear();
|
||||
}
|
||||
|
||||
/// Return the span associated with `handle`.
|
||||
///
|
||||
/// If a value has been inserted multiple times, the span returned is the
|
||||
/// one provided with the first insertion.
|
||||
///
|
||||
/// If the `span` feature is not enabled, always return `Span::default`.
|
||||
/// This can be detected with [`Span::is_defined`].
|
||||
pub fn get_span(&self, handle: Handle<T>) -> Span {
|
||||
#[cfg(feature = "span")]
|
||||
{
|
||||
*self
|
||||
.span_info
|
||||
.get(handle.index())
|
||||
.unwrap_or(&Span::default())
|
||||
}
|
||||
#[cfg(not(feature = "span"))]
|
||||
{
|
||||
let _ = handle;
|
||||
Span::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Eq + hash::Hash> UniqueArena<T> {
|
||||
/// Returns an iterator over the items stored in this arena, returning both
|
||||
/// the item's handle and a reference to it.
|
||||
pub fn iter(&self) -> impl DoubleEndedIterator<Item = (Handle<T>, &T)> {
|
||||
self.set.iter().enumerate().map(|(i, v)| {
|
||||
let position = i + 1;
|
||||
let index = unsafe { Index::new_unchecked(position as u32) };
|
||||
(Handle::new(index), v)
|
||||
})
|
||||
}
|
||||
|
||||
/// Insert a new value into the arena.
|
||||
///
|
||||
/// Return a [`Handle<T>`], which can be used to index this arena to get a
|
||||
/// shared reference to the element.
|
||||
///
|
||||
/// If this arena already contains an element that is `Eq` to `value`,
|
||||
/// return a `Handle` to the existing element, and drop `value`.
|
||||
///
|
||||
/// When the `span` feature is enabled, if `value` is inserted into the
|
||||
/// arena, associate `span` with it. An element's span can be retrieved with
|
||||
/// the [`get_span`] method.
|
||||
///
|
||||
/// [`Handle<T>`]: Handle
|
||||
/// [`get_span`]: UniqueArena::get_span
|
||||
pub fn fetch_or_append(&mut self, value: T, span: Span) -> Handle<T> {
|
||||
let (index, added) = self.set.insert_full(value);
|
||||
|
||||
#[cfg(feature = "span")]
|
||||
{
|
||||
if added {
|
||||
debug_assert!(index == self.span_info.len());
|
||||
self.span_info.push(span);
|
||||
}
|
||||
|
||||
debug_assert!(self.set.len() == self.span_info.len());
|
||||
}
|
||||
|
||||
Handle::from_usize(index)
|
||||
}
|
||||
|
||||
/// Return this arena's handle for `value`, if present.
|
||||
///
|
||||
/// If this arena already contains an element equal to `value`,
|
||||
/// return its handle. Otherwise, return `None`.
|
||||
pub fn get(&self, value: &T) -> Option<Handle<T>> {
|
||||
self.set
|
||||
.get_index_of(value)
|
||||
.map(|index| unsafe { Handle::from_usize_unchecked(index) })
|
||||
}
|
||||
|
||||
/// Return this arena's value at `handle`, if that is a valid handle.
|
||||
pub fn try_get(&self, handle: Handle<T>) -> Option<&T> {
|
||||
self.set.get_index(handle.index())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Default for UniqueArena<T> {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: fmt::Debug + Eq + hash::Hash> fmt::Debug for UniqueArena<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
f.debug_map().entries(self.iter()).finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> ops::Index<Handle<T>> for UniqueArena<T> {
|
||||
type Output = T;
|
||||
fn index(&self, handle: Handle<T>) -> &T {
|
||||
&self.set[handle.index()]
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serialize")]
|
||||
impl<T> serde::Serialize for UniqueArena<T>
|
||||
where
|
||||
T: Eq + hash::Hash,
|
||||
T: serde::Serialize,
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.set.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "deserialize")]
|
||||
impl<'de, T> serde::Deserialize<'de> for UniqueArena<T>
|
||||
where
|
||||
T: Eq + hash::Hash,
|
||||
T: serde::Deserialize<'de>,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let set = IndexSet::deserialize(deserializer)?;
|
||||
#[cfg(feature = "span")]
|
||||
let span_info = std::iter::repeat(Span::default()).take(set.len()).collect();
|
||||
|
||||
Ok(Self {
|
||||
set,
|
||||
#[cfg(feature = "span")]
|
||||
span_info,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ const ATOMIC_REFERENCE: &str = "&";
|
||||
|
||||
struct TypeContext<'a> {
|
||||
handle: Handle<crate::Type>,
|
||||
arena: &'a crate::Arena<crate::Type>,
|
||||
arena: &'a crate::UniqueArena<crate::Type>,
|
||||
names: &'a FastHashMap<NameKey, String>,
|
||||
access: crate::StorageAccess,
|
||||
first_time: bool,
|
||||
@@ -354,7 +354,7 @@ fn should_pack_struct_member(
|
||||
}
|
||||
}
|
||||
|
||||
fn needs_array_length(ty: Handle<crate::Type>, arena: &crate::Arena<crate::Type>) -> bool {
|
||||
fn needs_array_length(ty: Handle<crate::Type>, arena: &crate::UniqueArena<crate::Type>) -> bool {
|
||||
if let crate::TypeInner::Struct { ref members, .. } = arena[ty].inner {
|
||||
if let Some(member) = members.last() {
|
||||
if let crate::TypeInner::Array {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::{Arena, Handle};
|
||||
use crate::{Handle, UniqueArena};
|
||||
use spirv::Word;
|
||||
|
||||
pub(super) fn bytes_to_words(bytes: &[u8]) -> Vec<Word> {
|
||||
@@ -35,7 +35,7 @@ pub(super) fn map_storage_class(class: crate::StorageClass) -> spirv::StorageCla
|
||||
pub(super) fn contains_builtin(
|
||||
binding: Option<&crate::Binding>,
|
||||
ty: Handle<crate::Type>,
|
||||
arena: &Arena<crate::Type>,
|
||||
arena: &UniqueArena<crate::Type>,
|
||||
built_in: crate::BuiltIn,
|
||||
) -> bool {
|
||||
if let Some(&crate::Binding::BuiltIn(bi)) = binding {
|
||||
|
||||
@@ -6,7 +6,7 @@ use super::{
|
||||
PipelineOptions, ResultMember, Writer, WriterFlags, BITS_PER_BYTE,
|
||||
};
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Handle, UniqueArena},
|
||||
proc::TypeResolution,
|
||||
valid::{FunctionInfo, ModuleInfo},
|
||||
};
|
||||
@@ -195,7 +195,7 @@ impl Writer {
|
||||
|
||||
pub(super) fn get_pointer_id(
|
||||
&mut self,
|
||||
arena: &Arena<crate::Type>,
|
||||
arena: &UniqueArena<crate::Type>,
|
||||
handle: Handle<crate::Type>,
|
||||
class: spirv::StorageClass,
|
||||
) -> Result<Word, Error> {
|
||||
@@ -766,7 +766,7 @@ impl Writer {
|
||||
|
||||
fn write_type_declaration_arena(
|
||||
&mut self,
|
||||
arena: &Arena<crate::Type>,
|
||||
arena: &UniqueArena<crate::Type>,
|
||||
handle: Handle<crate::Type>,
|
||||
) -> Result<Word, Error> {
|
||||
let ty = &arena[handle];
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
BinaryOperator, Constant, ConstantInner, Expression, ScalarKind, ScalarValue, Type, TypeInner,
|
||||
UnaryOperator,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ConstantSolver<'a> {
|
||||
pub types: &'a mut Arena<Type>,
|
||||
pub types: &'a mut UniqueArena<Type>,
|
||||
pub expressions: &'a Arena<Expression>,
|
||||
pub constants: &'a mut Arena<Constant>,
|
||||
}
|
||||
@@ -531,18 +531,18 @@ mod tests {
|
||||
|
||||
use crate::{
|
||||
Arena, Constant, ConstantInner, Expression, ScalarKind, ScalarValue, Type, TypeInner,
|
||||
UnaryOperator, VectorSize,
|
||||
UnaryOperator, UniqueArena, VectorSize,
|
||||
};
|
||||
|
||||
use super::ConstantSolver;
|
||||
|
||||
#[test]
|
||||
fn unary_op() {
|
||||
let mut types = Arena::new();
|
||||
let mut types = UniqueArena::new();
|
||||
let mut expressions = Arena::new();
|
||||
let mut constants = Arena::new();
|
||||
|
||||
let vec_ty = types.append(
|
||||
let vec_ty = types.fetch_or_append(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
@@ -698,7 +698,7 @@ mod tests {
|
||||
);
|
||||
|
||||
let mut solver = ConstantSolver {
|
||||
types: &mut Arena::new(),
|
||||
types: &mut UniqueArena::new(),
|
||||
expressions: &expressions,
|
||||
constants: &mut constants,
|
||||
};
|
||||
@@ -716,11 +716,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn access() {
|
||||
let mut types = Arena::new();
|
||||
let mut types = UniqueArena::new();
|
||||
let mut expressions = Arena::new();
|
||||
let mut constants = Arena::new();
|
||||
|
||||
let matrix_ty = types.append(
|
||||
let matrix_ty = types.fetch_or_append(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Matrix {
|
||||
@@ -732,7 +732,7 @@ mod tests {
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let vec_ty = types.append(
|
||||
let vec_ty = types.fetch_or_append(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Vector {
|
||||
|
||||
@@ -900,7 +900,7 @@ impl Parser {
|
||||
}
|
||||
|
||||
let (ty, value) = if !components.is_empty() {
|
||||
let ty = self.module.types.append(
|
||||
let ty = self.module.types.fetch_or_append(
|
||||
Type {
|
||||
name: None,
|
||||
inner: TypeInner::Struct {
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::{
|
||||
error::{Error, ErrorKind},
|
||||
Span,
|
||||
};
|
||||
use crate::{front::align_up, Arena, Constant, Handle, Type, TypeInner};
|
||||
use crate::{front::align_up, Arena, Constant, Handle, Type, TypeInner, UniqueArena};
|
||||
|
||||
/// Struct with information needed for defining a struct member.
|
||||
///
|
||||
@@ -39,7 +39,7 @@ pub fn calculate_offset(
|
||||
mut ty: Handle<Type>,
|
||||
meta: Span,
|
||||
layout: StructLayout,
|
||||
types: &mut Arena<Type>,
|
||||
types: &mut UniqueArena<Type>,
|
||||
constants: &Arena<Constant>,
|
||||
errors: &mut Vec<Error>,
|
||||
) -> TypeAlignSpan {
|
||||
|
||||
@@ -497,7 +497,7 @@ impl<'source> ParsingContext<'source> {
|
||||
let span = self.parse_struct_declaration_list(parser, &mut members, layout)?;
|
||||
self.expect(parser, TokenValue::RightBrace)?;
|
||||
|
||||
let mut ty = parser.module.types.append(
|
||||
let mut ty = parser.module.types.fetch_or_append(
|
||||
Type {
|
||||
name: Some(ty_name),
|
||||
inner: TypeInner::Struct {
|
||||
|
||||
@@ -47,7 +47,7 @@ impl<'source> ParsingContext<'source> {
|
||||
self.parse_struct_declaration_list(parser, &mut members, StructLayout::Std140)?;
|
||||
let end_meta = self.expect(parser, TokenValue::RightBrace)?.meta;
|
||||
meta.subsume(end_meta);
|
||||
let ty = parser.module.types.append(
|
||||
let ty = parser.module.types.fetch_or_append(
|
||||
Type {
|
||||
name: Some(ty_name.clone()),
|
||||
inner: TypeInner::Struct {
|
||||
|
||||
@@ -10,7 +10,7 @@ pub mod spv;
|
||||
pub mod wgsl;
|
||||
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::{ResolveContext, ResolveError, TypeResolution},
|
||||
};
|
||||
use std::ops;
|
||||
@@ -81,7 +81,7 @@ impl Typifier {
|
||||
pub fn get<'a>(
|
||||
&'a self,
|
||||
expr_handle: Handle<crate::Expression>,
|
||||
types: &'a Arena<crate::Type>,
|
||||
types: &'a UniqueArena<crate::Type>,
|
||||
) -> &'a crate::TypeInner {
|
||||
self.resolutions[expr_handle.index()].inner_with(types)
|
||||
}
|
||||
|
||||
@@ -477,7 +477,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
|
||||
let span = crate::Span::total_span(
|
||||
components.iter().map(|h| function.expressions.get_span(*h)),
|
||||
);
|
||||
let ty = module.types.append(
|
||||
let ty = module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Struct {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
FunctionArgument,
|
||||
};
|
||||
|
||||
@@ -62,7 +62,7 @@ fn extract_image_coordinates(
|
||||
extra_coordinate: ExtraCoordinate,
|
||||
base: Handle<crate::Expression>,
|
||||
coordinate_ty: Handle<crate::Type>,
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
expressions: &mut Arena<crate::Expression>,
|
||||
) -> (Handle<crate::Expression>, Option<Handle<crate::Expression>>) {
|
||||
let (given_size, kind) = match type_arena[coordinate_ty].inner {
|
||||
@@ -74,13 +74,13 @@ fn extract_image_coordinates(
|
||||
let required_size = image_dim.required_coordinate_size();
|
||||
let required_ty = required_size.map(|size| {
|
||||
type_arena
|
||||
.fetch_if(|ty| {
|
||||
ty.inner
|
||||
== crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: 4,
|
||||
}
|
||||
.get(&crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
size,
|
||||
kind,
|
||||
width: 4,
|
||||
},
|
||||
})
|
||||
.expect("Required coordinate type should have been set up by `parse_type_image`!")
|
||||
});
|
||||
@@ -184,7 +184,7 @@ fn extract_image_coordinates(
|
||||
pub(super) fn patch_comparison_type(
|
||||
flags: SamplingFlags,
|
||||
var: &mut crate::GlobalVariable,
|
||||
arena: &mut Arena<crate::Type>,
|
||||
arena: &mut UniqueArena<crate::Type>,
|
||||
) -> bool {
|
||||
if !flags.contains(SamplingFlags::COMPARISON) {
|
||||
return true;
|
||||
@@ -211,7 +211,7 @@ pub(super) fn patch_comparison_type(
|
||||
};
|
||||
|
||||
let name = original_ty.name.clone();
|
||||
var.ty = arena.append(
|
||||
var.ty = arena.fetch_or_append(
|
||||
crate::Type {
|
||||
name,
|
||||
inner: ty_inner,
|
||||
@@ -257,7 +257,7 @@ impl<I: Iterator<Item = u32>> super::Parser<I> {
|
||||
pub(super) fn parse_image_write(
|
||||
&mut self,
|
||||
words_left: u16,
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
global_arena: &Arena<crate::GlobalVariable>,
|
||||
arguments: &[FunctionArgument],
|
||||
expressions: &mut Arena<crate::Expression>,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub use error::Error;
|
||||
use function::*;
|
||||
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::Layouter,
|
||||
FastHashMap,
|
||||
};
|
||||
@@ -495,7 +495,7 @@ struct BlockContext<'function> {
|
||||
/// Constants arena of the module being processed
|
||||
const_arena: &'function mut Arena<crate::Constant>,
|
||||
/// Type arena of the module being processed
|
||||
type_arena: &'function Arena<crate::Type>,
|
||||
type_arena: &'function UniqueArena<crate::Type>,
|
||||
/// Global arena of the module being processed
|
||||
global_arena: &'function Arena<crate::GlobalVariable>,
|
||||
/// Arguments of the function currently being processed
|
||||
@@ -991,7 +991,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
root_type_id: spirv::Word,
|
||||
object_expr: Handle<crate::Expression>,
|
||||
selections: &[spirv::Word],
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
expressions: &mut Arena<crate::Expression>,
|
||||
span: crate::Span,
|
||||
) -> Result<Handle<crate::Expression>, Error> {
|
||||
@@ -3388,7 +3388,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: self.future_decor.remove(&id).and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3423,7 +3423,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: self.future_decor.remove(&id).and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3453,7 +3453,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: self.future_decor.remove(&id).and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3490,7 +3490,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: self.future_decor.remove(&id).and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3529,7 +3529,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3593,7 +3593,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
base_lookup_ty.clone()
|
||||
} else {
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.and_then(|dec| dec.name),
|
||||
inner: crate::TypeInner::Pointer {
|
||||
@@ -3636,7 +3636,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.name,
|
||||
inner,
|
||||
@@ -3673,7 +3673,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
self.lookup_type.insert(
|
||||
id,
|
||||
LookupType {
|
||||
handle: module.types.append(
|
||||
handle: module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.name,
|
||||
inner,
|
||||
@@ -3777,7 +3777,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
members,
|
||||
};
|
||||
|
||||
let ty_handle = module.types.append(
|
||||
let ty_handle = module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: parent_decor.and_then(|dec| dec.name),
|
||||
inner,
|
||||
@@ -3862,7 +3862,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
arrayed: is_array,
|
||||
};
|
||||
|
||||
let handle = module.types.append(
|
||||
let handle = module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.name,
|
||||
inner,
|
||||
@@ -3905,7 +3905,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
inst.expect(2)?;
|
||||
let id = self.next()?;
|
||||
let decor = self.future_decor.remove(&id).unwrap_or_default();
|
||||
let handle = module.types.append(
|
||||
let handle = module.types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: decor.name,
|
||||
inner: crate::TypeInner::Sampler { comparison: false },
|
||||
@@ -4051,7 +4051,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
fn parse_null_constant(
|
||||
&mut self,
|
||||
inst: Instruction,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
constants: &mut Arena<crate::Constant>,
|
||||
) -> Result<(u32, u32, Handle<crate::Constant>), Error> {
|
||||
let start = self.data_offset;
|
||||
@@ -4151,7 +4151,7 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
class: crate::ImageClass::Storage { format, access },
|
||||
},
|
||||
};
|
||||
effective_ty = module.types.append(ty, Default::default());
|
||||
effective_ty = module.types.fetch_or_append(ty, Default::default());
|
||||
}
|
||||
|
||||
let ext_class = match self.lookup_storage_buffer_types.get(&effective_ty) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use super::Error;
|
||||
use crate::arena::{Arena, Handle};
|
||||
use crate::arena::{Arena, Handle, UniqueArena};
|
||||
|
||||
fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::ConstantInner {
|
||||
crate::ConstantInner::Scalar {
|
||||
@@ -15,7 +15,7 @@ fn make_scalar_inner(kind: crate::ScalarKind, width: crate::Bytes) -> crate::Con
|
||||
|
||||
pub fn generate_null_constant(
|
||||
ty: Handle<crate::Type>,
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
constant_arena: &mut Arena<crate::Constant>,
|
||||
span: crate::Span,
|
||||
) -> Result<crate::ConstantInner, Error> {
|
||||
@@ -42,13 +42,13 @@ pub fn generate_null_constant(
|
||||
} => {
|
||||
// If we successfully declared a matrix type, we have declared a vector type for it too.
|
||||
let vector_ty = type_arena
|
||||
.fetch_if(|t| {
|
||||
t.inner
|
||||
== crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size: rows,
|
||||
width,
|
||||
}
|
||||
.get(&crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
kind: crate::ScalarKind::Float,
|
||||
size: rows,
|
||||
width,
|
||||
},
|
||||
})
|
||||
.unwrap();
|
||||
let vector_inner = generate_null_constant(vector_ty, type_arena, constant_arena, span)?;
|
||||
@@ -116,7 +116,7 @@ pub fn generate_null_constant(
|
||||
pub fn generate_default_built_in(
|
||||
built_in: Option<crate::BuiltIn>,
|
||||
ty: Handle<crate::Type>,
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
constant_arena: &mut Arena<crate::Constant>,
|
||||
span: crate::Span,
|
||||
) -> Result<Handle<crate::Constant>, Error> {
|
||||
|
||||
@@ -9,7 +9,7 @@ mod number_literals;
|
||||
mod tests;
|
||||
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::{
|
||||
ensure_block_returns, Alignment, Layouter, ResolveContext, ResolveError, TypeResolution,
|
||||
},
|
||||
@@ -486,7 +486,11 @@ impl crate::TypeInner {
|
||||
/// For example `vec3<f32>`.
|
||||
///
|
||||
/// Note: The names of a `TypeInner::Struct` is not known. Therefore this method will simply return "struct" for them.
|
||||
fn to_wgsl(&self, types: &Arena<crate::Type>, constants: &Arena<crate::Constant>) -> String {
|
||||
fn to_wgsl(
|
||||
&self,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
constants: &Arena<crate::Constant>,
|
||||
) -> String {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
match *self {
|
||||
@@ -584,7 +588,7 @@ impl crate::TypeInner {
|
||||
mod type_inner_tests {
|
||||
#[test]
|
||||
fn to_wgsl() {
|
||||
let mut types = crate::Arena::new();
|
||||
let mut types = crate::UniqueArena::new();
|
||||
let mut constants = crate::Arena::new();
|
||||
let c = constants.append(
|
||||
crate::Constant {
|
||||
@@ -598,7 +602,7 @@ mod type_inner_tests {
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let mytype1 = types.append(
|
||||
let mytype1 = types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: Some("MyType1".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
@@ -609,7 +613,7 @@ mod type_inner_tests {
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
let mytype2 = types.append(
|
||||
let mytype2 = types.fetch_or_append(
|
||||
crate::Type {
|
||||
name: Some("MyType2".to_string()),
|
||||
inner: crate::TypeInner::Struct {
|
||||
@@ -707,7 +711,7 @@ struct StatementContext<'input, 'temp, 'out> {
|
||||
variables: &'out mut Arena<crate::LocalVariable>,
|
||||
expressions: &'out mut Arena<crate::Expression>,
|
||||
named_expressions: &'out mut FastHashMap<Handle<crate::Expression>, String>,
|
||||
types: &'out mut Arena<crate::Type>,
|
||||
types: &'out mut UniqueArena<crate::Type>,
|
||||
constants: &'out mut Arena<crate::Constant>,
|
||||
global_vars: &'out Arena<crate::GlobalVariable>,
|
||||
functions: &'out Arena<crate::Function>,
|
||||
@@ -763,7 +767,7 @@ struct ExpressionContext<'input, 'temp, 'out> {
|
||||
lookup_ident: &'temp FastHashMap<&'input str, TypedExpression>,
|
||||
typifier: &'temp mut super::Typifier,
|
||||
expressions: &'out mut Arena<crate::Expression>,
|
||||
types: &'out mut Arena<crate::Type>,
|
||||
types: &'out mut UniqueArena<crate::Type>,
|
||||
constants: &'out mut Arena<crate::Constant>,
|
||||
global_vars: &'out Arena<crate::GlobalVariable>,
|
||||
local_vars: &'out Arena<crate::LocalVariable>,
|
||||
@@ -1993,7 +1997,7 @@ impl Parser {
|
||||
first_token_span: TokenSpan<'a>,
|
||||
lexer: &mut Lexer<'a>,
|
||||
register_name: Option<&'a str>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<Handle<crate::Constant>, Error<'a>> {
|
||||
self.push_scope(Scope::ConstantExpr, lexer);
|
||||
@@ -2068,7 +2072,7 @@ impl Parser {
|
||||
fn parse_const_expression<'a>(
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<Handle<crate::Constant>, Error<'a>> {
|
||||
self.parse_const_expression_impl(lexer.next(), lexer, None, type_arena, const_arena)
|
||||
@@ -2560,7 +2564,7 @@ impl Parser {
|
||||
fn parse_variable_ident_decl<'a>(
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<(&'a str, Span, Handle<crate::Type>, crate::StorageAccess), Error<'a>> {
|
||||
let (name, name_span) = lexer.next_ident_with_span()?;
|
||||
@@ -2572,7 +2576,7 @@ impl Parser {
|
||||
fn parse_variable_decl<'a>(
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<ParsedVariable<'a>, Error<'a>> {
|
||||
self.push_scope(Scope::VariableDecl, lexer);
|
||||
@@ -2624,7 +2628,7 @@ impl Parser {
|
||||
fn parse_struct_body<'a>(
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<(Vec<crate::StructMember>, u32), Error<'a>> {
|
||||
let mut offset = 0;
|
||||
@@ -2722,7 +2726,7 @@ impl Parser {
|
||||
lexer: &mut Lexer<'a>,
|
||||
attribute: TypeAttributes,
|
||||
word: &'a str,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<Option<crate::TypeInner>, Error<'a>> {
|
||||
if let Some((kind, width)) = conv::get_scalar_type(word) {
|
||||
@@ -3034,7 +3038,7 @@ impl Parser {
|
||||
name_span: Span,
|
||||
debug_name: Option<&'a str>,
|
||||
attribute: TypeAttributes,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<Handle<crate::Type>, Error<'a>> {
|
||||
Ok(match self.lookup_type.get(name) {
|
||||
@@ -3061,7 +3065,7 @@ impl Parser {
|
||||
&mut self,
|
||||
lexer: &mut Lexer<'a>,
|
||||
debug_name: Option<&'a str>,
|
||||
type_arena: &mut Arena<crate::Type>,
|
||||
type_arena: &mut UniqueArena<crate::Type>,
|
||||
const_arena: &mut Arena<crate::Constant>,
|
||||
) -> Result<(Handle<crate::Type>, crate::StorageAccess), Error<'a>> {
|
||||
self.push_scope(Scope::TypeDecl, lexer);
|
||||
|
||||
21
src/lib.rs
21
src/lib.rs
@@ -44,6 +44,15 @@ and compound expressions refer to their sub-expressions via `Handle<Expression>`
|
||||
values. (When examining the serialized form of a `Module`, note that the first
|
||||
element of an `Arena` has an index of 1, not 0.)
|
||||
|
||||
A [`UniqueArena`] is just like an `Arena`, except that it stores only a single
|
||||
instance of each value. The value type must implement `Eq` and `Hash`. Like an
|
||||
`Arena`, inserting a value into a `UniqueArena` returns a `Handle` which can be
|
||||
used to efficiently access the value, without a hash lookup. Inserting a value
|
||||
multiple times returns the same `Handle`.
|
||||
|
||||
If the `span` feature is enabled, both `Arena` and `UniqueArena` can associate a
|
||||
source code span with each element.
|
||||
|
||||
## Function Calls
|
||||
|
||||
Naga's representation of function calls is unusual. Most languages treat
|
||||
@@ -203,7 +212,7 @@ pub mod proc;
|
||||
mod span;
|
||||
pub mod valid;
|
||||
|
||||
pub use crate::arena::{Arena, Handle, Range};
|
||||
pub use crate::arena::{Arena, Handle, Range, UniqueArena};
|
||||
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
@@ -412,7 +421,7 @@ pub enum Sampling {
|
||||
|
||||
/// Member of a user-defined structure.
|
||||
// Clone is used only for error reporting and is not intended for end users
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub struct StructMember {
|
||||
@@ -531,7 +540,7 @@ pub enum ImageClass {
|
||||
}
|
||||
|
||||
/// A data type declared in the module.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub struct Type {
|
||||
@@ -542,7 +551,7 @@ pub struct Type {
|
||||
}
|
||||
|
||||
/// Enum with additional information, depending on the kind of type.
|
||||
#[derive(Debug, PartialEq)]
|
||||
#[derive(Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub enum TypeInner {
|
||||
@@ -704,7 +713,7 @@ pub enum ConstantInner {
|
||||
}
|
||||
|
||||
/// Describes how an input/output variable is to be bound.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub enum Binding {
|
||||
@@ -1552,7 +1561,7 @@ pub struct EntryPoint {
|
||||
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||
pub struct Module {
|
||||
/// Storage for the types defined in this module.
|
||||
pub types: Arena<Type>,
|
||||
pub types: UniqueArena<Type>,
|
||||
/// Storage for the constants defined in this module.
|
||||
pub constants: Arena<Constant>,
|
||||
/// Storage for the global variables defined in this module.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::arena::{Arena, Handle};
|
||||
use crate::arena::{Arena, Handle, UniqueArena};
|
||||
use std::{num::NonZeroU32, ops};
|
||||
|
||||
pub type Alignment = NonZeroU32;
|
||||
@@ -64,7 +64,7 @@ impl Layouter {
|
||||
|
||||
pub fn update(
|
||||
&mut self,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
constants: &Arena<crate::Constant>,
|
||||
) -> Result<(), InvalidBaseType> {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::arena::{Arena, Handle};
|
||||
use crate::arena::{Arena, Handle, UniqueArena};
|
||||
|
||||
use thiserror::Error;
|
||||
|
||||
@@ -10,8 +10,8 @@ use thiserror::Error;
|
||||
/// You might expect such a function to simply return a `Handle<Type>`. However,
|
||||
/// we want type resolution to be a read-only process, and that would limit the
|
||||
/// possible results to types already present in the expression's associated
|
||||
/// `Arena<Type>`. Naga IR does have certain expressions whose types are not
|
||||
/// certain to be present.
|
||||
/// `UniqueArena<Type>`. Naga IR does have certain expressions whose types are
|
||||
/// not certain to be present.
|
||||
///
|
||||
/// So instead, type resolution returns a `TypeResolution` enum: either a
|
||||
/// [`Handle`], referencing some type in the arena, or a [`Value`], holding a
|
||||
@@ -104,7 +104,7 @@ impl TypeResolution {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner_with<'a>(&'a self, arena: &'a Arena<crate::Type>) -> &'a crate::TypeInner {
|
||||
pub fn inner_with<'a>(&'a self, arena: &'a UniqueArena<crate::Type>) -> &'a crate::TypeInner {
|
||||
match *self {
|
||||
Self::Handle(handle) => &arena[handle].inner,
|
||||
Self::Value(ref inner) => inner,
|
||||
@@ -197,7 +197,7 @@ pub enum ResolveError {
|
||||
|
||||
pub struct ResolveContext<'a> {
|
||||
pub constants: &'a Arena<crate::Constant>,
|
||||
pub types: &'a Arena<crate::Type>,
|
||||
pub types: &'a UniqueArena<crate::Type>,
|
||||
pub global_vars: &'a Arena<crate::GlobalVariable>,
|
||||
pub local_vars: &'a Arena<crate::LocalVariable>,
|
||||
pub functions: &'a Arena<crate::Function>,
|
||||
|
||||
@@ -53,7 +53,7 @@ impl Span {
|
||||
}
|
||||
|
||||
/// Check wether `self` was defined or is a default/unknown span
|
||||
fn is_defined(&self) -> bool {
|
||||
pub fn is_defined(&self) -> bool {
|
||||
*self != Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -869,8 +869,8 @@ fn uniform_control_flow() {
|
||||
},
|
||||
Default::default(),
|
||||
);
|
||||
let mut type_arena = Arena::new();
|
||||
let ty = type_arena.append(
|
||||
let mut type_arena = crate::UniqueArena::new();
|
||||
let ty = type_arena.fetch_or_append(
|
||||
crate::Type {
|
||||
name: None,
|
||||
inner: crate::TypeInner::Vector {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::TypeResolution,
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ pub enum ComposeError {
|
||||
pub fn validate_compose(
|
||||
self_ty_handle: Handle<crate::Type>,
|
||||
constant_arena: &Arena<crate::Constant>,
|
||||
type_arena: &Arena<crate::Type>,
|
||||
type_arena: &UniqueArena<crate::Type>,
|
||||
component_resolutions: impl ExactSizeIterator<Item = TypeResolution>,
|
||||
) -> Result<(), ComposeError> {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::{compose::validate_compose, ComposeError, FunctionInfo, ShaderStages, TypeFlags};
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Handle, UniqueArena},
|
||||
proc::{ProcError, ResolveError},
|
||||
};
|
||||
|
||||
@@ -113,7 +113,7 @@ pub enum ExpressionError {
|
||||
|
||||
struct ExpressionTypeResolver<'a> {
|
||||
root: Handle<crate::Expression>,
|
||||
types: &'a Arena<crate::Type>,
|
||||
types: &'a UniqueArena<crate::Type>,
|
||||
info: &'a FunctionInfo,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use super::{
|
||||
analyzer::{UniformityDisruptor, UniformityRequirements},
|
||||
ExpressionError, FunctionInfo, ModuleInfo, ShaderStages, TypeFlags, ValidationFlags,
|
||||
};
|
||||
use crate::arena::{Arena, Handle};
|
||||
use crate::arena::{Arena, Handle, UniqueArena};
|
||||
use bit_set::BitSet;
|
||||
|
||||
#[derive(Clone, Debug, thiserror::Error)]
|
||||
@@ -144,7 +144,7 @@ struct BlockContext<'a> {
|
||||
abilities: ControlFlowAbility,
|
||||
info: &'a FunctionInfo,
|
||||
expressions: &'a Arena<crate::Expression>,
|
||||
types: &'a Arena<crate::Type>,
|
||||
types: &'a UniqueArena<crate::Type>,
|
||||
global_vars: &'a Arena<crate::GlobalVariable>,
|
||||
functions: &'a Arena<crate::Function>,
|
||||
prev_infos: &'a [FunctionInfo],
|
||||
@@ -627,7 +627,7 @@ impl super::Validator {
|
||||
fn validate_local_var(
|
||||
&self,
|
||||
var: &crate::LocalVariable,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
constants: &Arena<crate::Constant>,
|
||||
) -> Result<(), LocalVariableError> {
|
||||
log::debug!("var {:?}", var);
|
||||
|
||||
@@ -3,7 +3,7 @@ use super::{
|
||||
Capabilities, Disalignment, FunctionError, ModuleInfo, ShaderStages, TypeFlags,
|
||||
ValidationFlags,
|
||||
};
|
||||
use crate::arena::{Arena, Handle};
|
||||
use crate::arena::{Handle, UniqueArena};
|
||||
|
||||
use bit_set::BitSet;
|
||||
|
||||
@@ -93,7 +93,7 @@ struct VaryingContext<'a> {
|
||||
ty: Handle<crate::Type>,
|
||||
stage: crate::ShaderStage,
|
||||
output: bool,
|
||||
types: &'a Arena<crate::Type>,
|
||||
types: &'a UniqueArena<crate::Type>,
|
||||
location_mask: &'a mut BitSet,
|
||||
built_in_mask: u32,
|
||||
capabilities: Capabilities,
|
||||
@@ -320,7 +320,7 @@ impl super::Validator {
|
||||
pub(super) fn validate_global_var(
|
||||
&self,
|
||||
var: &crate::GlobalVariable,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
) -> Result<(), GlobalVariableError> {
|
||||
log::debug!("var {:?}", var);
|
||||
let type_info = &self.types[var.ty.index()];
|
||||
|
||||
@@ -6,7 +6,7 @@ mod interface;
|
||||
mod r#type;
|
||||
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::{InvalidBaseType, Layouter},
|
||||
FastHashSet,
|
||||
};
|
||||
@@ -217,7 +217,7 @@ impl Validator {
|
||||
&self,
|
||||
handle: Handle<crate::Constant>,
|
||||
constants: &Arena<crate::Constant>,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
) -> Result<(), ConstantError> {
|
||||
let con = &constants[handle];
|
||||
match con.inner {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use super::Capabilities;
|
||||
use crate::{
|
||||
arena::{Arena, Handle},
|
||||
arena::{Arena, Handle, UniqueArena},
|
||||
proc::Alignment,
|
||||
};
|
||||
|
||||
@@ -187,7 +187,7 @@ impl super::Validator {
|
||||
pub(super) fn validate_type(
|
||||
&self,
|
||||
handle: Handle<crate::Type>,
|
||||
types: &Arena<crate::Type>,
|
||||
types: &UniqueArena<crate::Type>,
|
||||
constants: &Arena<crate::Constant>,
|
||||
) -> Result<TypeInfo, TypeError> {
|
||||
use crate::TypeInner as Ti;
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
ref_count: 0,
|
||||
assignable_global: Some(3),
|
||||
ty: Value(Pointer(
|
||||
base: 14,
|
||||
base: 13,
|
||||
class: Uniform,
|
||||
)),
|
||||
),
|
||||
@@ -95,7 +95,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: Some(1),
|
||||
ty: Handle(56),
|
||||
ty: Handle(30),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -106,7 +106,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: Some(2),
|
||||
ty: Handle(57),
|
||||
ty: Handle(31),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -118,7 +118,7 @@
|
||||
ref_count: 0,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 21,
|
||||
base: 20,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -770,7 +770,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Handle(9),
|
||||
ty: Handle(6),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -781,7 +781,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Handle(9),
|
||||
ty: Handle(6),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -792,7 +792,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Handle(9),
|
||||
ty: Handle(6),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -831,7 +831,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Handle(9),
|
||||
ty: Handle(6),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -857,7 +857,7 @@
|
||||
),
|
||||
ref_count: 2,
|
||||
assignable_global: None,
|
||||
ty: Handle(9),
|
||||
ty: Handle(6),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -1120,7 +1120,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(3),
|
||||
ty: Value(Pointer(
|
||||
base: 14,
|
||||
base: 13,
|
||||
class: Uniform,
|
||||
)),
|
||||
),
|
||||
@@ -1161,7 +1161,7 @@
|
||||
),
|
||||
ref_count: 0,
|
||||
assignable_global: Some(1),
|
||||
ty: Handle(56),
|
||||
ty: Handle(30),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -1172,7 +1172,7 @@
|
||||
),
|
||||
ref_count: 0,
|
||||
assignable_global: Some(2),
|
||||
ty: Handle(57),
|
||||
ty: Handle(31),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -1184,7 +1184,7 @@
|
||||
ref_count: 7,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 21,
|
||||
base: 20,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -1798,7 +1798,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(3),
|
||||
ty: Value(Pointer(
|
||||
base: 13,
|
||||
base: 12,
|
||||
class: Uniform,
|
||||
)),
|
||||
),
|
||||
@@ -1892,7 +1892,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -1921,7 +1921,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -1939,7 +1939,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 18,
|
||||
base: 17,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -1956,7 +1956,7 @@
|
||||
),
|
||||
ref_count: 1,
|
||||
assignable_global: None,
|
||||
ty: Handle(18),
|
||||
ty: Handle(17),
|
||||
),
|
||||
(
|
||||
uniformity: (
|
||||
@@ -2027,7 +2027,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2056,7 +2056,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2126,7 +2126,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2155,7 +2155,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2225,7 +2225,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2254,7 +2254,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2500,7 +2500,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2529,7 +2529,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2599,7 +2599,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2628,7 +2628,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2698,7 +2698,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 20,
|
||||
base: 19,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
@@ -2727,7 +2727,7 @@
|
||||
ref_count: 1,
|
||||
assignable_global: Some(4),
|
||||
ty: Value(Pointer(
|
||||
base: 19,
|
||||
base: 18,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 1,
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
|
||||
struct type10 {
|
||||
struct type9 {
|
||||
vec2 member;
|
||||
vec4 gen_gl_Position;
|
||||
float gen_gl_PointSize;
|
||||
@@ -47,7 +47,7 @@ void main() {
|
||||
float _e12 = perVertexStruct.gen_gl_PointSize;
|
||||
float _e13[1] = perVertexStruct.gen_gl_ClipDistance;
|
||||
float _e14[1] = perVertexStruct.gen_gl_CullDistance;
|
||||
type10 _tmp_return = type10(_e10, _e11, _e12, _e13, _e14);
|
||||
type9 _tmp_return = type9(_e10, _e11, _e12, _e13, _e14);
|
||||
_vs2fs_location0 = _tmp_return.member;
|
||||
gl_Position = _tmp_return.gen_gl_Position;
|
||||
gl_Position.yz = vec2(-gl_Position.y, gl_Position.z * 2.0 - gl_Position.w);
|
||||
|
||||
@@ -6,7 +6,7 @@ struct gl_PerVertex {
|
||||
float gl_CullDistance[1] : SV_CullDistance;
|
||||
};
|
||||
|
||||
struct type10 {
|
||||
struct type9 {
|
||||
linear float2 member : LOC0;
|
||||
float4 gl_Position : SV_Position;
|
||||
float gl_PointSize : PSIZE;
|
||||
@@ -36,8 +36,8 @@ void main1()
|
||||
return;
|
||||
}
|
||||
|
||||
type10 Constructtype10(float2 arg0, float4 arg1, float arg2, float arg3[1], float arg4[1]) {
|
||||
type10 ret;
|
||||
type9 Constructtype9(float2 arg0, float4 arg1, float arg2, float arg3[1], float arg4[1]) {
|
||||
type9 ret;
|
||||
ret.member = arg0;
|
||||
ret.gl_Position = arg1;
|
||||
ret.gl_PointSize = arg2;
|
||||
@@ -56,7 +56,7 @@ VertexOutput_main main(float2 a_uv : LOC1, float2 a_pos : LOC0)
|
||||
float _expr12 = perVertexStruct.gl_PointSize;
|
||||
float _expr13[1] = perVertexStruct.gl_ClipDistance;
|
||||
float _expr14[1] = perVertexStruct.gl_CullDistance;
|
||||
const type10 type10_ = Constructtype10(_expr10, _expr11, _expr12, _expr13, _expr14);
|
||||
const VertexOutput_main type10_1 = { type10_.member, type10_.gl_Position, type10_.gl_ClipDistance, type10_.gl_CullDistance, type10_.gl_PointSize };
|
||||
return type10_1;
|
||||
const type9 type9_ = Constructtype9(_expr10, _expr11, _expr12, _expr13, _expr14);
|
||||
const VertexOutput_main type9_1 = { type9_.member, type9_.gl_Position, type9_.gl_ClipDistance, type9_.gl_CullDistance, type9_.gl_PointSize };
|
||||
return type9_1;
|
||||
}
|
||||
|
||||
@@ -62,14 +62,6 @@
|
||||
comparison: false,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Vector(
|
||||
size: Bi,
|
||||
kind: Float,
|
||||
width: 4,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Scalar(
|
||||
@@ -106,7 +98,7 @@
|
||||
members: [
|
||||
(
|
||||
name: Some("num_lights"),
|
||||
ty: 13,
|
||||
ty: 12,
|
||||
binding: None,
|
||||
offset: 0,
|
||||
),
|
||||
@@ -117,14 +109,14 @@
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 14,
|
||||
base: 13,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 13,
|
||||
base: 12,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
@@ -150,7 +142,7 @@
|
||||
members: [
|
||||
(
|
||||
name: Some("proj"),
|
||||
ty: 18,
|
||||
ty: 17,
|
||||
binding: None,
|
||||
offset: 0,
|
||||
),
|
||||
@@ -173,7 +165,7 @@
|
||||
(
|
||||
name: None,
|
||||
inner: Array(
|
||||
base: 19,
|
||||
base: 18,
|
||||
size: Dynamic,
|
||||
stride: 96,
|
||||
),
|
||||
@@ -185,7 +177,7 @@
|
||||
members: [
|
||||
(
|
||||
name: Some("data"),
|
||||
ty: 20,
|
||||
ty: 19,
|
||||
binding: None,
|
||||
offset: 0,
|
||||
),
|
||||
@@ -196,7 +188,7 @@
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 21,
|
||||
base: 20,
|
||||
class: Storage(
|
||||
access: (
|
||||
bits: 0,
|
||||
@@ -204,13 +196,6 @@
|
||||
),
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
@@ -225,6 +210,13 @@
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 17,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
@@ -239,76 +231,6 @@
|
||||
class: Private,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
@@ -330,111 +252,6 @@
|
||||
class: Private,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Private,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Private,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 20,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 19,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 1,
|
||||
class: Uniform,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Pointer(
|
||||
base: 4,
|
||||
class: Private,
|
||||
),
|
||||
),
|
||||
(
|
||||
name: None,
|
||||
inner: Image(
|
||||
@@ -778,7 +595,7 @@
|
||||
group: 0,
|
||||
binding: 2,
|
||||
)),
|
||||
ty: 56,
|
||||
ty: 30,
|
||||
init: None,
|
||||
),
|
||||
(
|
||||
@@ -788,7 +605,7 @@
|
||||
group: 0,
|
||||
binding: 3,
|
||||
)),
|
||||
ty: 57,
|
||||
ty: 31,
|
||||
init: None,
|
||||
),
|
||||
(
|
||||
@@ -798,7 +615,7 @@
|
||||
group: 0,
|
||||
binding: 0,
|
||||
)),
|
||||
ty: 14,
|
||||
ty: 13,
|
||||
init: None,
|
||||
),
|
||||
(
|
||||
@@ -812,7 +629,7 @@
|
||||
group: 0,
|
||||
binding: 1,
|
||||
)),
|
||||
ty: 21,
|
||||
ty: 20,
|
||||
init: None,
|
||||
),
|
||||
(
|
||||
@@ -924,14 +741,14 @@
|
||||
index: 1,
|
||||
),
|
||||
Compose(
|
||||
ty: 9,
|
||||
ty: 6,
|
||||
components: [
|
||||
51,
|
||||
52,
|
||||
],
|
||||
),
|
||||
Compose(
|
||||
ty: 9,
|
||||
ty: 6,
|
||||
components: [
|
||||
13,
|
||||
22,
|
||||
|
||||
@@ -2,25 +2,25 @@
|
||||
#include <metal_stdlib>
|
||||
#include <simd/simd.h>
|
||||
|
||||
struct type6 {
|
||||
struct type5 {
|
||||
float inner[1u];
|
||||
};
|
||||
struct gl_PerVertex {
|
||||
metal::float4 gl_Position;
|
||||
float gl_PointSize;
|
||||
type6 gl_ClipDistance;
|
||||
type6 gl_CullDistance;
|
||||
type5 gl_ClipDistance;
|
||||
type5 gl_CullDistance;
|
||||
};
|
||||
struct type10 {
|
||||
struct type9 {
|
||||
metal::float2 member;
|
||||
metal::float4 gl_Position;
|
||||
float gl_PointSize;
|
||||
type6 gl_ClipDistance;
|
||||
type6 gl_CullDistance;
|
||||
type5 gl_ClipDistance;
|
||||
type5 gl_CullDistance;
|
||||
};
|
||||
constant metal::float4 const_type4_ = {0.0, 0.0, 0.0, 1.0};
|
||||
constant type6 const_type6_ = {0.0};
|
||||
constant gl_PerVertex const_gl_PerVertex = {const_type4_, 1.0, const_type6_, const_type6_};
|
||||
constant metal::float4 const_type3_ = {0.0, 0.0, 0.0, 1.0};
|
||||
constant type5 const_type5_ = {0.0};
|
||||
constant gl_PerVertex const_gl_PerVertex = {const_type3_, 1.0, const_type5_, const_type5_};
|
||||
|
||||
void main2(
|
||||
thread metal::float2& v_uv,
|
||||
@@ -60,8 +60,8 @@ vertex main1Output main1(
|
||||
metal::float2 _e10 = v_uv;
|
||||
metal::float4 _e11 = perVertexStruct.gl_Position;
|
||||
float _e12 = perVertexStruct.gl_PointSize;
|
||||
type6 _e13 = perVertexStruct.gl_ClipDistance;
|
||||
type6 _e14 = perVertexStruct.gl_CullDistance;
|
||||
const auto _tmp = type10 {_e10, _e11, _e12, _e13, _e14};
|
||||
type5 _e13 = perVertexStruct.gl_ClipDistance;
|
||||
type5 _e14 = perVertexStruct.gl_CullDistance;
|
||||
const auto _tmp = type9 {_e10, _e11, _e12, _e13, _e14};
|
||||
return main1Output { _tmp.member, _tmp.gl_Position, _tmp.gl_PointSize, {_tmp.gl_ClipDistance.inner[0]} };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user