Some shader parse refactoring and additions (#2414)

This commit is contained in:
Rua 2023-12-01 13:16:21 +01:00 committed by GitHub
parent 795f02217a
commit a17d8f5cb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 252 additions and 156 deletions

View File

@ -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::<Member>::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 },

View File

@ -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<Id> {
match self {
#(#result_type_id_items)|* => Some(*result_type_id),
_ => None
}
}
}
};
@ -325,6 +346,19 @@ fn bit_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> 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<KindEnumMember>)]) -> 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<KindEnumMember>)]) -> TokenStream {
})
}
}
impl From<u32> for #name {
fn from(value: u32) -> Self {
Self {
#(#from_items)*
}
}
}
}
});
@ -447,11 +489,11 @@ fn value_enum_output(enums: &[(Ident, Vec<KindEnumMember>)]) -> 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<KindEnumMember>)]) -> 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<KindEnumMember>)]) -> 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<KindEnumMember>)]) -> TokenStream {
})
}
}
impl TryFrom<u32> for #name {
type Error = ();
fn try_from(val: u32) -> Result<Self, Self::Error> {
match val {
#(#try_from_items)*
_ => Err(()),
}
}
}
}
});

View File

@ -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 {

View File

@ -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:

View File

@ -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,

View File

@ -22,7 +22,7 @@ use std::borrow::Cow;
pub fn entry_points(spirv: &Spirv) -> impl Iterator<Item = (Id, EntryPointInfo)> + '_ {
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<u32, Specializa
let get_constant_id = |result_id| {
spirv
.id(result_id)
.iter_decoration()
.decorations()
.iter()
.find_map(|instruction| match *instruction {
Instruction::Decorate {
decoration:
@ -994,7 +998,8 @@ pub(super) fn specialization_constants(spirv: &Spirv) -> HashMap<u32, Specializa
};
spirv
.iter_global()
.constants()
.iter()
.filter_map(|instruction| match *instruction {
Instruction::SpecConstantFalse { result_id, .. } => 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<DeviceSize> {
}
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<DeviceSize> {
} => {
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<DeviceSize> {
// 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<DeviceSize> {
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,

View File

@ -29,15 +29,17 @@ pub struct Spirv {
ids: HashMap<Id, IdInfo>,
// Items described in the spec section "Logical Layout of a Module"
instructions_capability: Vec<Instruction>,
instructions_extension: Vec<Instruction>,
instructions_ext_inst_import: Vec<Instruction>,
instruction_memory_model: Instruction,
instructions_entry_point: Vec<Instruction>,
instructions_execution_mode: Vec<Instruction>,
instructions_name: Vec<Instruction>,
instructions_decoration: Vec<Instruction>,
instructions_global: Vec<Instruction>,
capabilities: Vec<Instruction>,
extensions: Vec<Instruction>,
ext_inst_imports: Vec<Instruction>,
memory_model: Instruction,
entry_points: Vec<Instruction>,
execution_modes: Vec<Instruction>,
names: Vec<Instruction>,
decorations: Vec<Instruction>,
types: Vec<Instruction>,
constants: Vec<Instruction>,
global_variables: Vec<Instruction>,
functions: HashMap<Id, FunctionInfo>,
}
@ -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<Instruction>> = 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<Id, Vec<Instruction>> = 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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &FunctionInfo> {
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<Id, FunctionInfo> {
&self.functions
}
pub fn apply_specialization(
&mut self,
specialization_info: &HashMap<u32, SpecializationConstant>,
) {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &StructMemberInfo> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
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<Item = &Instruction> {
self.execution_modes.iter()
pub fn execution_modes(&self) -> &[Instruction] {
&self.execution_modes
}
}