mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-24 15:55:07 +00:00
Some shader parse refactoring and additions (#2414)
This commit is contained in:
parent
795f02217a
commit
a17d8f5cb5
@ -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 },
|
||||
|
@ -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(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user