mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-21 22:34:43 +00:00
Properly generate infos about descriptors in vulkano-shaders
This commit is contained in:
parent
3b04d46dbb
commit
c95d456926
@ -50,69 +50,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String {
|
||||
}).next().expect(&format!("Uniform `{}` is missing a binding", name));
|
||||
|
||||
// Find informations about the kind of binding for this descriptor.
|
||||
let (desc_ty, readonly) = doc.instructions.iter().filter_map(|i| {
|
||||
match i {
|
||||
&parse::Instruction::TypeStruct { result_id, .. } if result_id == pointed_ty => {
|
||||
// Determine whether there's a Block or BufferBlock decoration.
|
||||
let is_ssbo = doc.instructions.iter().filter_map(|i| {
|
||||
match i {
|
||||
&parse::Instruction::Decorate { target_id, decoration: enums::Decoration::DecorationBufferBlock, .. } if target_id == pointed_ty => {
|
||||
Some(true)
|
||||
},
|
||||
&parse::Instruction::Decorate { target_id, decoration: enums::Decoration::DecorationBlock, .. } if target_id == pointed_ty => {
|
||||
Some(false)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}).next().expect("Found a buffer uniform with neither the Block nor BufferBlock decorations");
|
||||
|
||||
// Determine whether there's a NonWritable decoration.
|
||||
let non_writable = false; // TODO: tricky because the decoration is on struct members
|
||||
|
||||
Some((format!("DescriptorDescTy::Buffer(DescriptorBufferDesc {{
|
||||
dynamic: Some(false),
|
||||
storage: {}
|
||||
}})", if is_ssbo { "true" } else { "false "}), true))
|
||||
},
|
||||
&parse::Instruction::TypeImage { result_id, sampled_type_id, ref dim, arrayed, ms,
|
||||
sampled, ref format, ref access, .. }
|
||||
if result_id == pointed_ty && sampled == Some(true) =>
|
||||
{
|
||||
// FIXME: wrong
|
||||
let desc = format!("DescriptorDescTy::Image(DescriptorImageDesc {{
|
||||
sampled: true,
|
||||
dimensions: DescriptorImageDescDimensions::TwoDimensional,
|
||||
format: None,
|
||||
multisampled: false,
|
||||
array_layers: DescriptorImageDescArray::NonArrayed,
|
||||
}})");
|
||||
|
||||
Some((desc, true))
|
||||
},
|
||||
&parse::Instruction::TypeImage { result_id, sampled_type_id, ref dim, arrayed, ms,
|
||||
sampled, ref format, ref access, .. }
|
||||
if result_id == pointed_ty && sampled == Some(false) =>
|
||||
{
|
||||
// FIXME: everything wrong here
|
||||
Some(("DescriptorDescTy::InputAttachment { multisampled: false, array_layers: DescriptorImageDescArray::NonArrayed }".to_owned(), true))
|
||||
},
|
||||
&parse::Instruction::TypeSampledImage { result_id, image_type_id }
|
||||
if result_id == pointed_ty =>
|
||||
{
|
||||
// FIXME: wrong
|
||||
let desc = format!("DescriptorDescTy::CombinedImageSampler(DescriptorImageDesc {{
|
||||
sampled: true,
|
||||
dimensions: DescriptorImageDescDimensions::TwoDimensional,
|
||||
format: None,
|
||||
multisampled: false,
|
||||
array_layers: DescriptorImageDescArray::NonArrayed,
|
||||
}})");
|
||||
|
||||
Some((desc, true))
|
||||
},
|
||||
_ => None, // TODO: other types
|
||||
}
|
||||
}).next().expect(&format!("Couldn't find relevant type for uniform `{}` (type {}, maybe unimplemented)", name, pointed_ty));
|
||||
let (desc_ty, readonly) = descriptor_infos(doc, pointed_ty, false).expect(&format!("Couldn't find relevant type for uniform `{}` (type {}, maybe unimplemented)", name, pointed_ty));
|
||||
|
||||
descriptors.push(Descriptor {
|
||||
name: name,
|
||||
@ -199,3 +137,125 @@ fn pointer_variable_ty(doc: &parse::Spirv, variable: u32) -> u32 {
|
||||
}
|
||||
}).next().unwrap()
|
||||
}
|
||||
|
||||
/// Returns a `DescriptorDescTy` constructor and a bool indicating whether the descriptor is
|
||||
/// read-only.
|
||||
///
|
||||
/// See also section 14.5.2 of the Vulkan specs: Descriptor Set Interface
|
||||
fn descriptor_infos(doc: &parse::Spirv, pointed_ty: u32, force_combined_image_sampled: bool)
|
||||
-> Option<(String, bool)>
|
||||
{
|
||||
doc.instructions.iter().filter_map(|i| {
|
||||
match i {
|
||||
&parse::Instruction::TypeStruct { result_id, .. } if result_id == pointed_ty => {
|
||||
// Determine whether there's a Block or BufferBlock decoration.
|
||||
let is_ssbo = doc.instructions.iter().filter_map(|i| {
|
||||
match i {
|
||||
&parse::Instruction::Decorate
|
||||
{ target_id, decoration: enums::Decoration::DecorationBufferBlock, .. }
|
||||
if target_id == pointed_ty =>
|
||||
{
|
||||
Some(true)
|
||||
},
|
||||
&parse::Instruction::Decorate
|
||||
{ target_id, decoration: enums::Decoration::DecorationBlock, .. }
|
||||
if target_id == pointed_ty =>
|
||||
{
|
||||
Some(false)
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}).next().expect("Found a buffer uniform with neither the Block nor BufferBlock \
|
||||
decorations");
|
||||
|
||||
// Determine whether there's a NonWritable decoration.
|
||||
let non_writable = false; // TODO: tricky because the decoration is on struct members
|
||||
|
||||
let desc = format!("DescriptorDescTy::Buffer(DescriptorBufferDesc {{
|
||||
dynamic: Some(false),
|
||||
storage: {}
|
||||
}})", if is_ssbo { "true" } else { "false "});
|
||||
|
||||
Some((desc, true))
|
||||
},
|
||||
|
||||
&parse::Instruction::TypeImage { result_id, sampled_type_id, ref dim, arrayed, ms,
|
||||
sampled, ref format, ref access, .. }
|
||||
if result_id == pointed_ty =>
|
||||
{
|
||||
let sampled = sampled.expect("Vulkan requires that variables of type OpTypeImage \
|
||||
have a Sampled operand of 1 or 2");
|
||||
|
||||
let ms = if ms { "true" } else { "false" };
|
||||
let arrayed = if arrayed {
|
||||
"DescriptorImageDescArray::Arrayed { max_layers: None }"
|
||||
} else {
|
||||
"DescriptorImageDescArray::NonArrayed"
|
||||
};
|
||||
|
||||
if let &enums::Dim::DimSubpassData = dim {
|
||||
// We are an input attachment.
|
||||
assert!(!force_combined_image_sampled, "An OpTypeSampledImage can't point to \
|
||||
an OpTypeImage whose dimension is \
|
||||
SubpassData");
|
||||
assert!(if let &enums::ImageFormat::ImageFormatUnknown = format { true }
|
||||
else { false }, "If Dim is SubpassData, Image Format must be Unknown");
|
||||
assert!(!sampled, "If Dim is SubpassData, Sampled must be 2");
|
||||
|
||||
let desc = format!("DescriptorDescTy::InputAttachment {{
|
||||
multisampled: {},
|
||||
array_layers: {}
|
||||
}}", ms, arrayed);
|
||||
|
||||
Some((desc, true))
|
||||
|
||||
} else if let &enums::Dim::DimBuffer = dim {
|
||||
// We are a texel buffer.
|
||||
let desc = format!("DescriptorDescTy::TexelBuffer {{
|
||||
sampled: {},
|
||||
format: None, // TODO: specify format if known
|
||||
}}", sampled);
|
||||
|
||||
Some((desc, true))
|
||||
|
||||
} else {
|
||||
// We are a sampled or storage image.
|
||||
let sampled = if sampled { "true" } else { "false" };
|
||||
let ty = if force_combined_image_sampled { "CombinedImageSampler" }
|
||||
else { "Image" };
|
||||
let dim = match *dim {
|
||||
enums::Dim::Dim1D => "DescriptorImageDescDimensions::OneDimensional",
|
||||
enums::Dim::Dim2D => "DescriptorImageDescDimensions::TwoDimensional",
|
||||
enums::Dim::Dim3D => "DescriptorImageDescDimensions::ThreeDimensional",
|
||||
enums::Dim::DimCube => "DescriptorImageDescDimensions::Cube",
|
||||
enums::Dim::DimRect => panic!("Vulkan doesn't support rectangle textures"),
|
||||
_ => unreachable!()
|
||||
};
|
||||
|
||||
let desc = format!("DescriptorDescTy::{}(DescriptorImageDesc {{
|
||||
sampled: {},
|
||||
dimensions: {},
|
||||
format: None, // TODO: specify format if known
|
||||
multisampled: {},
|
||||
array_layers: {},
|
||||
}})", ty, sampled, dim, ms, arrayed);
|
||||
|
||||
Some((desc, true))
|
||||
}
|
||||
},
|
||||
|
||||
&parse::Instruction::TypeSampledImage { result_id, image_type_id }
|
||||
if result_id == pointed_ty =>
|
||||
{
|
||||
descriptor_infos(doc, image_type_id, true)
|
||||
},
|
||||
|
||||
&parse::Instruction::TypeSampler { result_id } if result_id == pointed_ty => {
|
||||
let desc = format!("DescriptorDescTy::Sampler");
|
||||
Some((desc, true))
|
||||
},
|
||||
|
||||
_ => None, // TODO: other types
|
||||
}
|
||||
}).next()
|
||||
}
|
||||
|
@ -101,6 +101,7 @@ pub enum Instruction {
|
||||
TypeVector { result_id: u32, component_id: u32, count: u32 },
|
||||
TypeMatrix { result_id: u32, column_type_id: u32, column_count: u32 },
|
||||
TypeImage { result_id: u32, sampled_type_id: u32, dim: Dim, depth: Option<bool>, arrayed: bool, ms: bool, sampled: Option<bool>, format: ImageFormat, access: Option<AccessQualifier> },
|
||||
TypeSampler { result_id: u32 },
|
||||
TypeSampledImage { result_id: u32, image_type_id: u32 },
|
||||
TypeArray { result_id: u32, type_id: u32, length_id: u32 },
|
||||
TypeRuntimeArray { result_id: u32, type_id: u32 },
|
||||
@ -170,6 +171,7 @@ fn decode_instruction(opcode: u16, operands: &[u32]) -> Result<Instruction, Pars
|
||||
format: try!(ImageFormat::from_num(operands[7])),
|
||||
access: if operands.len() >= 9 { Some(try!(AccessQualifier::from_num(operands[8]))) } else { None },
|
||||
},
|
||||
26 => Instruction::TypeSampler { result_id: operands[0] },
|
||||
27 => Instruction::TypeSampledImage { result_id: operands[0], image_type_id: operands[1] },
|
||||
28 => Instruction::TypeArray { result_id: operands[0], type_id: operands[1], length_id: operands[2] },
|
||||
29 => Instruction::TypeRuntimeArray { result_id: operands[0], type_id: operands[1] },
|
||||
|
Loading…
Reference in New Issue
Block a user