From a17d8f5cb5cca28b745ba0dd115ed1f1b6a013a3 Mon Sep 17 00:00:00 2001 From: Rua Date: Fri, 1 Dec 2023 13:16:21 +0100 Subject: [PATCH] Some shader parse refactoring and additions (#2414) --- vulkano-shaders/src/structs.rs | 29 ++-- vulkano/autogen/spirv_parse.rs | 71 ++++++++- vulkano/src/pipeline/graphics/mod.rs | 5 +- vulkano/src/pipeline/mod.rs | 10 +- vulkano/src/shader/mod.rs | 6 +- vulkano/src/shader/reflect.rs | 70 +++++---- vulkano/src/shader/spirv/mod.rs | 217 ++++++++++++++------------- 7 files changed, 252 insertions(+), 156 deletions(-) diff --git a/vulkano-shaders/src/structs.rs b/vulkano-shaders/src/structs.rs index e1319586..6d44408b 100644 --- a/vulkano-shaders/src/structs.rs +++ b/vulkano-shaders/src/structs.rs @@ -94,7 +94,8 @@ pub(super) fn write_structs( for (struct_id, member_type_ids) in shader .spirv - .iter_global() + .types() + .iter() .filter_map(|instruction| match *instruction { Instruction::TypeStruct { result_id, @@ -130,10 +131,10 @@ pub(super) fn write_structs( } fn has_defined_layout(shader: &Shader, struct_id: Id) -> bool { - for member_info in shader.spirv.id(struct_id).iter_members() { + for member_info in shader.spirv.id(struct_id).members() { let mut offset_found = false; - for instruction in member_info.iter_decoration() { + for instruction in member_info.decorations() { match instruction { Instruction::MemberDecorate { decoration: Decoration::BuiltIn { .. }, @@ -616,7 +617,8 @@ impl TypeArray { shader .spirv .id(array_id) - .iter_decoration() + .decorations() + .iter() .filter_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::ArrayStride { array_stride }, @@ -680,7 +682,8 @@ impl TypeStruct { let id_info = shader.spirv.id(struct_id); let ident = id_info - .iter_name() + .names() + .iter() .find_map(|instruction| match instruction { Instruction::Name { name, .. } => Some(Ident::new(name, Span::call_site())), _ => None, @@ -689,13 +692,12 @@ impl TypeStruct { let mut members = Vec::::with_capacity(member_type_ids.len()); - for (member_index, (&member_id, member_info)) in member_type_ids - .iter() - .zip(id_info.iter_members()) - .enumerate() + for (member_index, (&member_id, member_info)) in + member_type_ids.iter().zip(id_info.members()).enumerate() { let ident = member_info - .iter_name() + .names() + .iter() .find_map(|instruction| match instruction { Instruction::MemberName { name, .. } => { Some(Ident::new(name, Span::call_site())) @@ -717,7 +719,7 @@ impl TypeStruct { if let Type::Matrix(matrix) = ty { let mut strides = - member_info.iter_decoration().filter_map( + member_info.decorations().iter().filter_map( |instruction| match *instruction { Instruction::MemberDecorate { decoration: Decoration::MatrixStride { matrix_stride }, @@ -748,7 +750,7 @@ impl TypeStruct { ); } - let mut majornessess = member_info.iter_decoration().filter_map( + let mut majornessess = member_info.decorations().iter().filter_map( |instruction| match *instruction { Instruction::MemberDecorate { decoration: Decoration::ColMajor, @@ -785,7 +787,8 @@ impl TypeStruct { } let offset = member_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::MemberDecorate { decoration: Decoration::Offset { byte_offset }, diff --git a/vulkano/autogen/spirv_parse.rs b/vulkano/autogen/spirv_parse.rs index 8cf6bb25..cecbda24 100644 --- a/vulkano/autogen/spirv_parse.rs +++ b/vulkano/autogen/spirv_parse.rs @@ -174,6 +174,19 @@ fn instruction_output(members: &[InstructionMember], spec_constant: bool) -> Tok } }, ); + let result_type_id_items = members.iter().filter_map( + |InstructionMember { + name, + has_result_type_id, + .. + }| { + if *has_result_type_id { + Some(quote! { Self::#name { result_type_id, .. } }) + } else { + None + } + }, + ); quote! { /// Returns the `Id` that is assigned by this instruction, if any. @@ -183,6 +196,14 @@ fn instruction_output(members: &[InstructionMember], spec_constant: bool) -> Tok _ => None } } + + /// Returns the `Id` of the type of `result_id`, if any. + pub fn result_type_id(&self) -> Option { + match self { + #(#result_type_id_items)|* => Some(*result_type_id), + _ => None + } + } } }; @@ -325,6 +346,19 @@ fn bit_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { } }, ); + let from_items = members.iter().map( + |KindEnumMember { + name, + value, + parameters, + }| { + if parameters.is_empty() { + quote! { #name: value & #value != 0, } + } else { + quote! { #name: None, } + } + }, + ); let parse_items = members.iter().map( |KindEnumMember { name, @@ -356,7 +390,7 @@ fn bit_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { ); quote! { - #[derive(Clone, Copy, Debug, PartialEq, Eq)] + #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[allow(non_camel_case_types)] pub struct #name { #(#members_items)* @@ -372,6 +406,14 @@ fn bit_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { }) } } + + impl From for #name { + fn from(value: u32) -> Self { + Self { + #(#from_items)* + } + } + } } }); @@ -447,11 +489,11 @@ fn value_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { let enum_items = enums.iter().map(|(name, members)| { let members_items = members.iter().map( |KindEnumMember { - name, parameters, .. + name, value, parameters, .. }| { if parameters.is_empty() { quote! { - #name, + #name = #value, } } else { let params = parameters.iter().map(|OperandMember { name, ty, .. }| { @@ -460,11 +502,17 @@ fn value_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { quote! { #name { #(#params)* - }, + } = #value, } } }, ); + let try_from_items = members + .iter() + .filter(|member| member.parameters.is_empty()) + .map(|KindEnumMember { name, value, .. }| { + quote! { #value => Ok(Self::#name), } + }); let parse_items = members.iter().map( |KindEnumMember { name, @@ -495,14 +543,14 @@ fn value_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { let name_string = name.to_string(); let derives = match name_string.as_str() { - "ExecutionModel" => quote! { #[derive(Clone, Copy, Debug, Hash, PartialEq, Eq)] }, "Decoration" => quote! { #[derive(Clone, Debug, PartialEq)] }, - _ => quote! { #[derive(Clone, Copy, Debug, PartialEq, Eq)] }, + _ => quote! { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] }, }; quote! { #derives #[allow(non_camel_case_types)] + #[repr(u32)] pub enum #name { #(#members_items)* } @@ -516,6 +564,17 @@ fn value_enum_output(enums: &[(Ident, Vec)]) -> TokenStream { }) } } + + impl TryFrom for #name { + type Error = (); + + fn try_from(val: u32) -> Result { + match val { + #(#try_from_items)* + _ => Err(()), + } + } + } } }); diff --git a/vulkano/src/pipeline/graphics/mod.rs b/vulkano/src/pipeline/graphics/mod.rs index 62adc856..8464533e 100644 --- a/vulkano/src/pipeline/graphics/mod.rs +++ b/vulkano/src/pipeline/graphics/mod.rs @@ -918,7 +918,7 @@ impl GraphicsPipeline { if matches!(entry_point_info.execution_model, ExecutionModel::Fragment) { fragment_tests_stages = Some(FragmentTestsStages::Late); - for instruction in entry_point_function.iter_execution_mode() { + for instruction in entry_point_function.execution_modes() { if let Instruction::ExecutionMode { mode, .. } = *instruction { match mode { ExecutionMode::EarlyFragmentTests => { @@ -2431,7 +2431,8 @@ impl GraphicsPipelineCreateInfo { let entry_point_function = spirv.function(geometry_stage.entry_point.id()); let input = entry_point_function - .iter_execution_mode() + .execution_modes() + .iter() .find_map(|instruction| { if let Instruction::ExecutionMode { mode, .. } = *instruction { match mode { diff --git a/vulkano/src/pipeline/mod.rs b/vulkano/src/pipeline/mod.rs index 2ad4ffef..7eb6ac90 100644 --- a/vulkano/src/pipeline/mod.rs +++ b/vulkano/src/pipeline/mod.rs @@ -451,7 +451,7 @@ impl PipelineShaderStageCreateInfo { let mut clip_distance_array_size = 0; let mut cull_distance_array_size = 0; - for instruction in spirv.iter_decoration() { + for instruction in spirv.decorations() { if let Instruction::Decorate { target, decoration: Decoration::BuiltIn { built_in }, @@ -556,7 +556,7 @@ impl PipelineShaderStageCreateInfo { })); } - for instruction in entry_point_function.iter_execution_mode() { + for instruction in entry_point_function.execution_modes() { if let Instruction::ExecutionMode { mode: ExecutionMode::OutputVertices { vertex_count }, .. @@ -617,7 +617,8 @@ impl PipelineShaderStageCreateInfo { } let local_size = (spirv - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { target, @@ -647,7 +648,8 @@ impl PipelineShaderStageCreateInfo { })) .or_else(|| { entry_point_function - .iter_execution_mode() + .execution_modes() + .iter() .find_map(|instruction| match *instruction { Instruction::ExecutionMode { mode: diff --git a/vulkano/src/shader/mod.rs b/vulkano/src/shader/mod.rs index 3d6faf80..24e6cbba 100644 --- a/vulkano/src/shader/mod.rs +++ b/vulkano/src/shader/mod.rs @@ -528,7 +528,8 @@ impl<'a> ShaderModuleCreateInfo<'a> { })?; for &capability in spirv - .iter_capability() + .capabilities() + .iter() .filter_map(|instruction| match instruction { Instruction::Capability { capability } => Some(capability), _ => None, @@ -538,7 +539,8 @@ impl<'a> ShaderModuleCreateInfo<'a> { } for extension in spirv - .iter_extension() + .extensions() + .iter() .filter_map(|instruction| match instruction { Instruction::Extension { name } => Some(name.as_str()), _ => None, diff --git a/vulkano/src/shader/reflect.rs b/vulkano/src/shader/reflect.rs index 57d6543e..46f2971b 100644 --- a/vulkano/src/shader/reflect.rs +++ b/vulkano/src/shader/reflect.rs @@ -22,7 +22,7 @@ use std::borrow::Cow; pub fn entry_points(spirv: &Spirv) -> impl Iterator + '_ { let interface_variables = interface_variables(spirv); - spirv.iter_entry_point().filter_map(move |instruction| { + spirv.entry_points().iter().filter_map(move |instruction| { let (execution_model, function_id, entry_point_name, interface) = match *instruction { Instruction::EntryPoint { execution_model, @@ -97,7 +97,7 @@ struct DescriptorBindingVariable { fn interface_variables(spirv: &Spirv) -> InterfaceVariables { let mut variables = InterfaceVariables::default(); - for instruction in spirv.iter_global() { + for instruction in spirv.global_variables() { if let Instruction::Variable { result_id, result_type_id, @@ -213,7 +213,7 @@ fn inspect_entry_point( self.inspected_functions.insert(function); - for instruction in self.spirv.function(function).iter_instructions() { + for instruction in self.spirv.function(function).instructions() { let stage = self.stage; match *instruction { @@ -635,7 +635,7 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip next_type_id = match *id_info.instruction() { Instruction::TypeStruct { .. } => { - let decoration_block = id_info.iter_decoration().any(|instruction| { + let decoration_block = id_info.decorations().iter().any(|instruction| { matches!( instruction, Instruction::Decorate { @@ -645,7 +645,7 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip ) }); - let decoration_buffer_block = id_info.iter_decoration().any(|instruction| { + let decoration_buffer_block = id_info.decorations().iter().any(|instruction| { matches!( instruction, Instruction::Decorate { @@ -813,7 +813,8 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip _ => { let name = variable_id_info - .iter_name() + .names() + .iter() .find_map(|instruction| match *instruction { Instruction::Name { ref name, .. } => Some(name.as_str()), _ => None, @@ -831,7 +832,8 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip DescriptorBindingVariable { set: variable_id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::DescriptorSet { descriptor_set }, @@ -841,7 +843,8 @@ fn descriptor_binding_requirements_of(spirv: &Spirv, variable_id: Id) -> Descrip }) .unwrap(), binding: variable_id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::Binding { binding_point }, @@ -898,7 +901,7 @@ fn push_constant_requirements( ) { visited_fns.insert(function_id); let function_info = spirv.function(function_id); - for instruction in function_info.iter_instructions() { + for instruction in function_info.instructions() { match instruction { Instruction::FunctionCall { function, @@ -980,7 +983,8 @@ pub(super) fn specialization_constants(spirv: &Spirv) -> HashMap HashMap get_constant_id(result_id) .map(|constant_id| (constant_id, SpecializationConstant::Bool(false))), @@ -1087,14 +1092,16 @@ fn shader_interface( let id_info = spirv.id(result_id); let name = id_info - .iter_name() + .names() + .iter() .find_map(|instruction| match *instruction { Instruction::Name { ref name, .. } => Some(Cow::Owned(name.clone())), _ => None, }); let location = id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::Location { location }, @@ -1109,7 +1116,8 @@ fn shader_interface( ) }); let component = id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::Component { component }, @@ -1119,7 +1127,8 @@ fn shader_interface( }) .unwrap_or(0); let index = id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::Index { index }, @@ -1198,7 +1207,8 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option { } Instruction::TypeArray { length, .. } => { let stride = id_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::Decorate { decoration: Decoration::ArrayStride { array_stride }, @@ -1226,9 +1236,9 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option { } => { let mut end_of_struct = 0; - for (&member, member_info) in member_types.iter().zip(id_info.iter_members()) { + for (&member, member_info) in member_types.iter().zip(id_info.members()) { // Built-ins have an unknown size. - if member_info.iter_decoration().any(|instruction| { + if member_info.decorations().iter().any(|instruction| { matches!( instruction, Instruction::MemberDecorate { @@ -1243,15 +1253,15 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option { // Some structs don't have `Offset` decorations, in the case they are used as local // variables only. Ignoring these. let offset = - member_info - .iter_decoration() - .find_map(|instruction| match *instruction { + member_info.decorations().iter().find_map( + |instruction| match *instruction { Instruction::MemberDecorate { decoration: Decoration::Offset { byte_offset }, .. } => Some(byte_offset), _ => None, - })?; + }, + )?; let size = size_of_type(spirv, member)?; end_of_struct = end_of_struct.max(offset as DeviceSize + size); } @@ -1266,10 +1276,12 @@ fn size_of_type(spirv: &Spirv, id: Id) -> Option { fn offset_of_struct(spirv: &Spirv, id: Id) -> u32 { spirv .id(id) - .iter_members() + .members() + .iter() .filter_map(|member_info| { member_info - .iter_decoration() + .decorations() + .iter() .find_map(|instruction| match *instruction { Instruction::MemberDecorate { decoration: Decoration::Offset { byte_offset }, @@ -1355,7 +1367,8 @@ fn shader_interface_type_of( } else { let mut ty = shader_interface_type_of(spirv, element_type, false); let num_elements = spirv - .iter_global() + .constants() + .iter() .find_map(|instruction| match *instruction { Instruction::Constant { result_id, @@ -1384,7 +1397,7 @@ fn shader_interface_type_of( fn is_builtin(spirv: &Spirv, id: Id) -> bool { let id_info = spirv.id(id); - if id_info.iter_decoration().any(|instruction| { + if id_info.decorations().iter().any(|instruction| { matches!( instruction, Instruction::Decorate { @@ -1397,8 +1410,9 @@ fn is_builtin(spirv: &Spirv, id: Id) -> bool { } if id_info - .iter_members() - .flat_map(|member_info| member_info.iter_decoration()) + .members() + .iter() + .flat_map(|member_info| member_info.decorations()) .any(|instruction| { matches!( instruction, diff --git a/vulkano/src/shader/spirv/mod.rs b/vulkano/src/shader/spirv/mod.rs index 2db062c3..fc5cc1ad 100644 --- a/vulkano/src/shader/spirv/mod.rs +++ b/vulkano/src/shader/spirv/mod.rs @@ -29,15 +29,17 @@ pub struct Spirv { ids: HashMap, // Items described in the spec section "Logical Layout of a Module" - instructions_capability: Vec, - instructions_extension: Vec, - instructions_ext_inst_import: Vec, - instruction_memory_model: Instruction, - instructions_entry_point: Vec, - instructions_execution_mode: Vec, - instructions_name: Vec, - instructions_decoration: Vec, - instructions_global: Vec, + capabilities: Vec, + extensions: Vec, + ext_inst_imports: Vec, + memory_model: Instruction, + entry_points: Vec, + execution_modes: Vec, + names: Vec, + decorations: Vec, + types: Vec, + constants: Vec, + global_variables: Vec, functions: HashMap, } @@ -62,15 +64,17 @@ impl Spirv { let mut bound = 0; let mut ids = HashMap::default(); - let mut instructions_capability = Vec::new(); - let mut instructions_extension = Vec::new(); - let mut instructions_ext_inst_import = Vec::new(); - let mut instructions_memory_model = Vec::new(); - let mut instructions_entry_point = Vec::new(); - let mut instructions_execution_mode = Vec::new(); - let mut instructions_name = Vec::new(); - let mut instructions_decoration = Vec::new(); - let mut instructions_global = Vec::new(); + let mut capabilities = Vec::new(); + let mut extensions = Vec::new(); + let mut ext_inst_imports = Vec::new(); + let mut memory_models = Vec::new(); + let mut entry_points = Vec::new(); + let mut execution_modes = Vec::new(); + let mut names = Vec::new(); + let mut decorations = Vec::new(); + let mut types = Vec::new(); + let mut constants = Vec::new(); + let mut global_variables = Vec::new(); let mut functions = HashMap::default(); let mut current_function: Option<&mut Vec> = None; @@ -124,7 +128,7 @@ impl Spirv { Instruction::Function { result_id, .. } => { current_function = None; let function = functions.entry(result_id).or_insert_with(|| { - let entry_point = instructions_entry_point + let entry_point = entry_points .iter() .find(|instruction| { matches!( @@ -134,7 +138,7 @@ impl Spirv { ) }) .cloned(); - let execution_modes = instructions_execution_mode + let execution_modes = execution_modes .iter() .filter(|instruction| { matches!( @@ -155,17 +159,15 @@ impl Spirv { }); current_function.insert(&mut function.instructions) } - Instruction::Capability { .. } => &mut instructions_capability, - Instruction::Extension { .. } => &mut instructions_extension, - Instruction::ExtInstImport { .. } => &mut instructions_ext_inst_import, - Instruction::MemoryModel { .. } => &mut instructions_memory_model, - Instruction::EntryPoint { .. } => &mut instructions_entry_point, + Instruction::Capability { .. } => &mut capabilities, + Instruction::Extension { .. } => &mut extensions, + Instruction::ExtInstImport { .. } => &mut ext_inst_imports, + Instruction::MemoryModel { .. } => &mut memory_models, + Instruction::EntryPoint { .. } => &mut entry_points, Instruction::ExecutionMode { .. } | Instruction::ExecutionModeId { .. } => { - &mut instructions_execution_mode - } - Instruction::Name { .. } | Instruction::MemberName { .. } => { - &mut instructions_name + &mut execution_modes } + Instruction::Name { .. } | Instruction::MemberName { .. } => &mut names, Instruction::Decorate { .. } | Instruction::MemberDecorate { .. } | Instruction::DecorationGroup { .. } @@ -173,7 +175,7 @@ impl Spirv { | Instruction::GroupMemberDecorate { .. } | Instruction::DecorateId { .. } | Instruction::DecorateString { .. } - | Instruction::MemberDecorateString { .. } => &mut instructions_decoration, + | Instruction::MemberDecorateString { .. } => &mut decorations, Instruction::TypeVoid { .. } | Instruction::TypeBool { .. } | Instruction::TypeInt { .. } @@ -212,8 +214,8 @@ impl Spirv { | Instruction::TypeAvcImeSingleReferenceStreaminINTEL { .. } | Instruction::TypeAvcImeDualReferenceStreaminINTEL { .. } | Instruction::TypeAvcRefResultINTEL { .. } - | Instruction::TypeAvcSicResultINTEL { .. } - | Instruction::ConstantTrue { .. } + | Instruction::TypeAvcSicResultINTEL { .. } => &mut types, + Instruction::ConstantTrue { .. } | Instruction::ConstantFalse { .. } | Instruction::Constant { .. } | Instruction::ConstantComposite { .. } @@ -225,8 +227,8 @@ impl Spirv { | Instruction::SpecConstant { .. } | Instruction::SpecConstantComposite { .. } | Instruction::SpecConstantOp { .. } - | Instruction::Variable { .. } - | Instruction::Undef { .. } => &mut instructions_global, + | Instruction::Undef { .. } => &mut constants, + Instruction::Variable { .. } => &mut global_variables, _ => continue, }; @@ -234,12 +236,12 @@ impl Spirv { } } - let instruction_memory_model = instructions_memory_model.drain(..).next().unwrap(); + let memory_model = memory_models.drain(..).next().unwrap(); // Add decorations to ids, // while also expanding decoration groups into individual decorations. let mut decoration_groups: HashMap> = HashMap::default(); - let instructions_decoration = instructions_decoration + let decorations = decorations .into_iter() .flat_map(|instruction| -> SmallVec<[Instruction; 1]> { match instruction { @@ -362,7 +364,7 @@ impl Spirv { }) .collect(); - instructions_name.retain(|instruction| match *instruction { + names.retain(|instruction| match *instruction { Instruction::Name { target, .. } => { if let Some(id_info) = ids.get_mut(&target) { id_info.names.push(instruction.clone()); @@ -389,15 +391,17 @@ impl Spirv { bound, ids, - instructions_capability, - instructions_extension, - instructions_ext_inst_import, - instruction_memory_model, - instructions_entry_point, - instructions_execution_mode, - instructions_name, - instructions_decoration, - instructions_global, + capabilities, + extensions, + ext_inst_imports, + memory_model, + entry_points, + execution_modes, + names, + decorations, + types, + constants, + global_variables, functions, }) } @@ -430,79 +434,90 @@ impl Spirv { &self.functions[&id] } - /// Returns an iterator over all `Capability` instructions. + /// Returns all `Capability` instructions. #[inline] - pub fn iter_capability(&self) -> impl ExactSizeIterator { - self.instructions_capability.iter() + pub fn capabilities(&self) -> &[Instruction] { + &self.capabilities } - /// Returns an iterator over all `Extension` instructions. + /// Returns all `Extension` instructions. #[inline] - pub fn iter_extension(&self) -> impl ExactSizeIterator { - self.instructions_extension.iter() + pub fn extensions(&self) -> &[Instruction] { + &self.extensions } - /// Returns an iterator over all `ExtInstImport` instructions. + /// Returns all `ExtInstImport` instructions. #[inline] - pub fn iter_ext_inst_import(&self) -> impl ExactSizeIterator { - self.instructions_ext_inst_import.iter() + pub fn ext_inst_imports(&self) -> &[Instruction] { + &self.ext_inst_imports } /// Returns the `MemoryModel` instruction. #[inline] pub fn memory_model(&self) -> &Instruction { - &self.instruction_memory_model + &self.memory_model } - /// Returns an iterator over all `EntryPoint` instructions. + /// Returns all `EntryPoint` instructions. #[inline] - pub fn iter_entry_point(&self) -> impl ExactSizeIterator { - self.instructions_entry_point.iter() + pub fn entry_points(&self) -> &[Instruction] { + &self.entry_points } - /// Returns an iterator over all execution mode instructions. + /// Returns all execution mode instructions. #[inline] - pub fn iter_execution_mode(&self) -> impl ExactSizeIterator { - self.instructions_execution_mode.iter() + pub fn execution_modes(&self) -> &[Instruction] { + &self.execution_modes } - /// Returns an iterator over all name debug instructions. + /// Returns all name debug instructions. #[inline] - pub fn iter_name(&self) -> impl ExactSizeIterator { - self.instructions_name.iter() + pub fn names(&self) -> &[Instruction] { + &self.names } - /// Returns an iterator over all decoration instructions. + /// Returns all decoration instructions. #[inline] - pub fn iter_decoration(&self) -> impl ExactSizeIterator { - self.instructions_decoration.iter() + pub fn decorations(&self) -> &[Instruction] { + &self.decorations } - /// Returns an iterator over all global declaration instructions: types, - /// constants and global variables. + /// Returns all type instructions. #[inline] - pub fn iter_global(&self) -> impl ExactSizeIterator { - self.instructions_global.iter() + pub fn types(&self) -> &[Instruction] { + &self.types } - /// Returns an iterator over all functions. + /// Returns all constant and specialization constant instructions. #[inline] - pub fn iter_functions(&self) -> impl ExactSizeIterator { - self.functions.values() + pub fn constants(&self) -> &[Instruction] { + &self.constants + } + + /// Returns all global variable instructions. + #[inline] + pub fn global_variables(&self) -> &[Instruction] { + &self.global_variables + } + + /// Returns all functions. + #[inline] + pub fn functions(&self) -> &HashMap { + &self.functions } pub fn apply_specialization( &mut self, specialization_info: &HashMap, ) { - self.instructions_global = specialization::replace_specialization_instructions( + self.constants = specialization::replace_specialization_instructions( specialization_info, - self.instructions_global.drain(..), + self.constants.drain(..), &self.ids, self.bound, ); - for instruction in &self.instructions_global { + for instruction in &self.constants { if let Some(id) = instruction.result_id() { if let Some(id_info) = self.ids.get_mut(&id) { id_info.instruction = instruction.clone(); @@ -530,7 +545,7 @@ impl Spirv { } } - self.instructions_decoration.retain(|instruction| { + self.decorations.retain(|instruction| { !matches!( instruction, Instruction::Decorate { @@ -587,23 +602,23 @@ impl IdInfo { &self.instruction } - /// Returns an iterator over all name debug instructions that target this `Id`. + /// Returns all name debug instructions that target this `Id`. #[inline] - pub fn iter_name(&self) -> impl ExactSizeIterator { - self.names.iter() + pub fn names(&self) -> &[Instruction] { + &self.names } - /// Returns an iterator over all decorate instructions, that target this `Id`. + /// Returns all decorate instructions that target this `Id`. #[inline] - pub fn iter_decoration(&self) -> impl ExactSizeIterator { - self.decorations.iter() + pub fn decorations(&self) -> &[Instruction] { + &self.decorations } - /// If this `Id` refers to a `TypeStruct`, returns an iterator of information about each member - /// of the struct. Empty otherwise. + /// If this `Id` refers to a `TypeStruct`, returns information about each member of the struct. + /// Empty otherwise. #[inline] - pub fn iter_members(&self) -> impl ExactSizeIterator { - self.members.iter() + pub fn members(&self) -> &[StructMemberInfo] { + &self.members } } @@ -615,16 +630,16 @@ pub struct StructMemberInfo { } impl StructMemberInfo { - /// Returns an iterator over all name debug instructions that target this struct member. + /// Returns all name debug instructions that target this struct member. #[inline] - pub fn iter_name(&self) -> impl ExactSizeIterator { - self.names.iter() + pub fn names(&self) -> &[Instruction] { + &self.names } - /// Returns an iterator over all decorate instructions that target this struct member. + /// Returns all decorate instructions that target this struct member. #[inline] - pub fn iter_decoration(&self) -> impl ExactSizeIterator { - self.decorations.iter() + pub fn decorations(&self) -> &[Instruction] { + &self.decorations } } @@ -637,10 +652,10 @@ pub struct FunctionInfo { } impl FunctionInfo { - /// Returns an iterator over all instructions in the function. + /// Returns the instructions in the function. #[inline] - pub fn iter_instructions(&self) -> impl ExactSizeIterator { - self.instructions.iter() + pub fn instructions(&self) -> &[Instruction] { + &self.instructions } /// Returns the `EntryPoint` instruction that targets this function, if there is one. @@ -649,10 +664,10 @@ impl FunctionInfo { self.entry_point.as_ref() } - /// Returns an iterator over all execution mode instructions that target this function. + /// Returns all execution mode instructions that target this function. #[inline] - pub fn iter_execution_mode(&self) -> impl ExactSizeIterator { - self.execution_modes.iter() + pub fn execution_modes(&self) -> &[Instruction] { + &self.execution_modes } }