diff --git a/codegen/sr.rs b/codegen/sr.rs index 300b6554..73f9812b 100644 --- a/codegen/sr.rs +++ b/codegen/sr.rs @@ -157,7 +157,12 @@ pub fn gen_sr_type_check(grammar: &structs::Grammar) -> String { let param_list: Vec<_> = params .iter() .map(|&(ref name, ref ty)| { - quote! { #name : #ty } + // structures support per-member decorations + if symbol == "Struct" { + quote! { #name : Vec } + } else { + quote! { #name : #ty } + } }) .collect(); let param_list = if param_list.is_empty() { @@ -256,7 +261,7 @@ pub fn gen_sr_type_creation(grammar: &structs::Grammar) -> String { }; quote! { pub fn #func_name #param_list -> TypeToken { - let t = Type { ty: TypeEnum::#symbol #init_list, decorations: BTreeSet::new() }; + let t = Type { ty: TypeEnum::#symbol #init_list, decorations: Vec::new() }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) } else { diff --git a/rspirv/sr/autogen_type_creation.rs b/rspirv/sr/autogen_type_creation.rs index 740fa149..86a440dd 100644 --- a/rspirv/sr/autogen_type_creation.rs +++ b/rspirv/sr/autogen_type_creation.rs @@ -20,7 +20,7 @@ impl Context { pub fn type_void(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::Void, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -32,7 +32,7 @@ impl Context { pub fn type_bool(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::Bool, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -47,7 +47,7 @@ impl Context { width: width, signedness: signedness, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -59,7 +59,7 @@ impl Context { pub fn type_float(&mut self, width: u32) -> TypeToken { let t = Type { ty: TypeEnum::Float { width: width }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -74,7 +74,7 @@ impl Context { component_type: component_type, component_count: component_count, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -89,7 +89,7 @@ impl Context { column_type: column_type, column_count: column_count, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -120,7 +120,7 @@ impl Context { image_format: image_format, access_qualifier: access_qualifier, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -132,7 +132,7 @@ impl Context { pub fn type_sampler(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::Sampler, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -146,7 +146,7 @@ impl Context { ty: TypeEnum::SampledImage { image_type: image_type, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -161,7 +161,7 @@ impl Context { element_type: element_type, length: length, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -175,7 +175,7 @@ impl Context { ty: TypeEnum::RuntimeArray { element_type: element_type, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -189,7 +189,7 @@ impl Context { ty: TypeEnum::Opaque { type_name: type_name, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -208,7 +208,7 @@ impl Context { storage_class: storage_class, pointee_type: pointee_type, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -227,7 +227,7 @@ impl Context { return_type: return_type, parameter_types: parameter_types, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -239,7 +239,7 @@ impl Context { pub fn type_event(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::Event, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -251,7 +251,7 @@ impl Context { pub fn type_device_event(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::DeviceEvent, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -263,7 +263,7 @@ impl Context { pub fn type_reserve_id(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::ReserveId, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -275,7 +275,7 @@ impl Context { pub fn type_queue(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::Queue, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -289,7 +289,7 @@ impl Context { ty: TypeEnum::Pipe { qualifier: qualifier, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -303,7 +303,7 @@ impl Context { ty: TypeEnum::ForwardPointer { storage_class: storage_class, }, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -315,7 +315,7 @@ impl Context { pub fn type_pipe_storage(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::PipeStorage, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) @@ -327,7 +327,7 @@ impl Context { pub fn type_named_barrier(&mut self) -> TypeToken { let t = Type { ty: TypeEnum::NamedBarrier, - decorations: BTreeSet::new(), + decorations: Vec::new(), }; if let Some(index) = self.types.iter().position(|x| *x == t) { TypeToken::new(index) diff --git a/rspirv/sr/autogen_type_enum_check.rs b/rspirv/sr/autogen_type_enum_check.rs index 5d22180b..9d30618e 100644 --- a/rspirv/sr/autogen_type_enum_check.rs +++ b/rspirv/sr/autogen_type_enum_check.rs @@ -57,7 +57,7 @@ pub(in sr) enum TypeEnum { element_type: TypeToken, }, Struct { - field_types: Vec, + field_types: Vec, }, Opaque { type_name: String, diff --git a/rspirv/sr/context.rs b/rspirv/sr/context.rs index d982711b..c5c13c7a 100644 --- a/rspirv/sr/context.rs +++ b/rspirv/sr/context.rs @@ -14,11 +14,9 @@ use spirv; -use std::collections::BTreeSet; - use super::{Type, TypeToken, Constant, ConstantToken}; use sr::constants::ConstantEnum; -use sr::types::TypeEnum; +use sr::types::{StructMember, TypeEnum}; /// The context class for SPIR-V structured representation. /// @@ -36,7 +34,7 @@ pub struct Context { } impl Context { - pub fn new() -> Context { + pub fn new() -> Self { Context { types: vec![], constants: vec![], @@ -49,8 +47,14 @@ include!("autogen_type_creation.rs"); impl Context { pub fn type_struct>(&mut self, field_types: T) -> TypeToken { self.types.push(Type { - ty: TypeEnum::Struct { field_types: field_types.as_ref().to_vec() }, - decorations: BTreeSet::new(), + ty: TypeEnum::Struct { + field_types: field_types + .as_ref() + .iter() + .map(|ft| StructMember::new(*ft)) + .collect(), + }, + decorations: Vec::new(), }); TypeToken::new(self.types.len() - 1) } diff --git a/rspirv/sr/types.rs b/rspirv/sr/types.rs index 1d63b3dd..182f5331 100644 --- a/rspirv/sr/types.rs +++ b/rspirv/sr/types.rs @@ -14,8 +14,6 @@ use spirv; -use std::collections::BTreeSet; - use super::{ConstantToken, Decoration}; /// The class to represent a SPIR-V type. @@ -26,14 +24,29 @@ use super::{ConstantToken, Decoration}; #[derive(Clone, Debug, PartialEq, Eq)] pub struct Type { pub(in sr) ty: TypeEnum, - /// Sets of decorations. Each element is a pair of an optional member index and the decoration. - pub(in sr) decorations: BTreeSet<(Option, Decoration)>, + /// Sets of decorations. + pub(in sr) decorations: Vec, } /// A token for representing a SPIR-V type. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct TypeToken { - index: usize + index: usize, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(in sr) struct StructMember { + pub(in sr) token: TypeToken, + pub(in sr) decorations: Vec, +} + +impl StructMember { + pub(in sr) fn new(token: TypeToken) -> Self { + StructMember { + token, + decorations: Vec::new(), + } + } } include!("autogen_type_enum_check.rs"); @@ -57,7 +70,7 @@ impl Type { } impl TypeToken { - pub(in sr) fn new(index: usize) -> TypeToken { + pub(in sr) fn new(index: usize) -> Self { TypeToken { index: index } }