diff --git a/vulkano-shaders/src/descriptor_sets.rs b/vulkano-shaders/src/descriptor_sets.rs index dd69789c..c180d457 100644 --- a/vulkano-shaders/src/descriptor_sets.rs +++ b/vulkano-shaders/src/descriptor_sets.rs @@ -69,28 +69,46 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String { // Determine whether there's a NonWritable decoration. let non_writable = false; // TODO: tricky because the decoration is on struct members - Some(if !is_ssbo { - ("DescriptorType::UniformBuffer", true) - } else { - ("DescriptorType::StorageBuffer", non_writable) - }) + 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) => { - Some(("DescriptorType::SampledImage", 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) => { - Some(("DescriptorType::InputAttachment", true)) // FIXME: can be `StorageImage` + // 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 => { - Some(("DescriptorType::CombinedImageSampler", true)) + // 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 } @@ -98,7 +116,7 @@ pub fn write_descriptor_sets(doc: &parse::Spirv) -> String { descriptors.push(Descriptor { name: name, - desc_ty: desc_ty.to_owned(), + desc_ty: desc_ty, set: descriptor_set, binding: binding, readonly: readonly, diff --git a/vulkano-shaders/src/lib.rs b/vulkano-shaders/src/lib.rs index 36e176c6..fa474080 100644 --- a/vulkano-shaders/src/lib.rs +++ b/vulkano-shaders/src/lib.rs @@ -72,7 +72,11 @@ pub fn reflect(name: &str, mut spirv: R) -> Result use vulkano::device::Device; use vulkano::descriptor::descriptor::DescriptorDesc; - use vulkano::descriptor::descriptor::DescriptorType; + use vulkano::descriptor::descriptor::DescriptorDescTy; + use vulkano::descriptor::descriptor::DescriptorBufferDesc; + use vulkano::descriptor::descriptor::DescriptorImageDesc; + use vulkano::descriptor::descriptor::DescriptorImageDescDimensions; + use vulkano::descriptor::descriptor::DescriptorImageDescArray; use vulkano::descriptor::descriptor::ShaderStages; use vulkano::descriptor::descriptor_set::DescriptorSet; use vulkano::descriptor::descriptor_set::UnsafeDescriptorSet; diff --git a/vulkano/src/descriptor/descriptor.rs b/vulkano/src/descriptor/descriptor.rs index 74f28cc9..a8d946ab 100644 --- a/vulkano/src/descriptor/descriptor.rs +++ b/vulkano/src/descriptor/descriptor.rs @@ -7,6 +7,7 @@ // notice may not be copied, modified, or distributed except // according to those terms. +use format::Format; use vk; /// Describes a single descriptor. @@ -15,8 +16,8 @@ pub struct DescriptorDesc { /// Offset of the binding within the descriptor. pub binding: u32, - /// What kind of resource can later be bound to this descriptor. - pub ty: DescriptorType, + /// Describes the content and layout of each array element of a descriptor. + pub ty: DescriptorDescTy, /// How many array elements this descriptor is made of. pub array_count: u32, @@ -35,14 +36,129 @@ impl DescriptorDesc { /// array elements count, or it is the same with more shader stages. #[inline] pub fn is_superset_of(&self, other: &DescriptorDesc) -> bool { - self.binding == other.binding && self.ty == other.ty && + self.binding == other.binding && self.ty.is_superset_of(&other.ty) && self.array_count >= other.array_count && self.stages.is_superset_of(&other.stages) && (!self.readonly || other.readonly) } } +/// Describes the content and layout of each array element of a descriptor. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum DescriptorDescTy { + Sampler, // TODO: the sampler has some restrictions as well + CombinedImageSampler(DescriptorImageDesc), // TODO: the sampler has some restrictions as well + Image(DescriptorImageDesc), + TexelBuffer { sampled: bool, format: Option }, + InputAttachment { multisampled: bool, array_layers: DescriptorImageDescArray }, + Buffer(DescriptorBufferDesc), +} + +impl DescriptorDescTy { + /// Returns the type of descriptor. + /// + /// Returns `None` if there's not enough info to determine the type. + pub fn ty(&self) -> Option { + Some(match *self { + DescriptorDescTy::Sampler => DescriptorType::Sampler, + DescriptorDescTy::CombinedImageSampler(_) => DescriptorType::CombinedImageSampler, + DescriptorDescTy::Image(desc) => { + if desc.sampled { DescriptorType::SampledImage } + else { DescriptorType::StorageImage } + }, + DescriptorDescTy::InputAttachment { .. } => DescriptorType::InputAttachment, + DescriptorDescTy::Buffer(desc) => { + let dynamic = match desc.dynamic { Some(d) => d, None => return None }; + match (desc.storage, dynamic) { + (false, false) => DescriptorType::UniformBuffer, + (true, false) => DescriptorType::StorageBuffer, + (false, true) => DescriptorType::UniformBufferDynamic, + (true, true) => DescriptorType::StorageBufferDynamic, + } + }, + DescriptorDescTy::TexelBuffer { sampled, .. } => { + if sampled { DescriptorType::UniformTexelBuffer } + else { DescriptorType::StorageTexelBuffer } + }, + }) + } + + /// Checks whether we are a superset of another descriptor type. + #[inline] + pub fn is_superset_of(&self, other: &DescriptorDescTy) -> bool { + true // FIXME: + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct DescriptorImageDesc { + pub sampled: bool, + pub dimensions: DescriptorImageDescDimensions, + /// The format of the image, or `None` if the format is unknown. + pub format: Option, + /// True if the image is multisampled. + pub multisampled: bool, + pub array_layers: DescriptorImageDescArray, +} + +impl DescriptorImageDesc { + /// Checks whether we are a superset of another image. + #[inline] + pub fn is_superset_of(&self, other: &DescriptorImageDesc) -> bool { + if self.dimensions != other.dimensions { + return false; + } + + if self.multisampled != other.multisampled { + return false; + } + + match (self.format, other.format) { + (Some(a), Some(b)) => if a != b { return false; }, + (Some(_), None) => (), + (None, None) => (), + (None, Some(_)) => return false, + }; + + match (self.array_layers, other.array_layers) { + (DescriptorImageDescArray::NonArrayed, DescriptorImageDescArray::NonArrayed) => (), + (DescriptorImageDescArray::Arrayed { max_layers: my_max }, + DescriptorImageDescArray::Arrayed { max_layers: other_max }) => + { + match (my_max, other_max) { + (Some(m), Some(o)) => if m < o { return false; }, + (Some(_), None) => (), + (None, _) => return false, + }; + }, + _ => return false + }; + + true + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum DescriptorImageDescArray { + NonArrayed, + Arrayed { max_layers: Option } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum DescriptorImageDescDimensions { + OneDimensional, + TwoDimensional, + ThreeDimensional, + Cube, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct DescriptorBufferDesc { + pub dynamic: Option, + pub storage: bool, + // FIXME: store content +} + /// Describes what kind of resource may later be bound to a descriptor. -// FIXME: add immutable sampler when relevant #[derive(Debug, Copy, Clone, PartialEq, Eq)] #[repr(u32)] pub enum DescriptorType { @@ -59,17 +175,6 @@ pub enum DescriptorType { InputAttachment = vk::DESCRIPTOR_TYPE_INPUT_ATTACHMENT, } -impl DescriptorType { - /// Turns the `DescriptorType` into the corresponding Vulkan constant. - // this function exists because when immutable samplers are added, it will no longer be possible to do `as u32` - // TODO: hacky - #[inline] - #[doc(hidden)] - pub fn vk_enum(&self) -> u32 { - *self as u32 - } -} - /// Describes which shader stages have access to a descriptor. #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct ShaderStages { diff --git a/vulkano/src/descriptor/descriptor_set/unsafe_layout.rs b/vulkano/src/descriptor/descriptor_set/unsafe_layout.rs index 7cf6567d..68875add 100644 --- a/vulkano/src/descriptor/descriptor_set/unsafe_layout.rs +++ b/vulkano/src/descriptor/descriptor_set/unsafe_layout.rs @@ -41,7 +41,7 @@ impl UnsafeDescriptorSetLayout { let bindings = descriptors.into_iter().map(|desc| { vk::DescriptorSetLayoutBinding { binding: desc.binding, - descriptorType: desc.ty.vk_enum(), + descriptorType: desc.ty.ty().unwrap() /* TODO: shouldn't panic */ as u32, descriptorCount: desc.array_count, stageFlags: desc.stages.into(), pImmutableSamplers: ptr::null(), // FIXME: not yet implemented diff --git a/vulkano/src/descriptor/pipeline_layout/custom_pipeline_macro.rs b/vulkano/src/descriptor/pipeline_layout/custom_pipeline_macro.rs index 9b841617..43eb6ab7 100644 --- a/vulkano/src/descriptor/pipeline_layout/custom_pipeline_macro.rs +++ b/vulkano/src/descriptor/pipeline_layout/custom_pipeline_macro.rs @@ -11,7 +11,11 @@ use std::marker::PhantomData; use std::sync::Arc; use buffer::TypedBuffer; -use descriptor::descriptor::DescriptorType; +use descriptor::descriptor::DescriptorDescTy; +use descriptor::descriptor::DescriptorBufferDesc; +use descriptor::descriptor::DescriptorImageDesc; +use descriptor::descriptor::DescriptorImageDescDimensions; +use descriptor::descriptor::DescriptorImageDescArray; use descriptor::descriptor_set::DescriptorWrite; use image::ImageView; use sampler::Sampler; @@ -247,14 +251,17 @@ pub unsafe trait ValidParameter { } pub unsafe trait DescriptorMarker { - fn descriptor_type() -> DescriptorType; + fn descriptor_type() -> DescriptorDescTy; } pub struct UniformBuffer(PhantomData); unsafe impl DescriptorMarker for UniformBuffer { #[inline] - fn descriptor_type() -> DescriptorType { - DescriptorType::UniformBuffer + fn descriptor_type() -> DescriptorDescTy { + DescriptorDescTy::Buffer(DescriptorBufferDesc { + dynamic: Some(false), + storage: false, + }) } } @@ -270,8 +277,11 @@ unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter> for &'a pub struct StorageBuffer(PhantomData); unsafe impl DescriptorMarker for StorageBuffer { #[inline] - fn descriptor_type() -> DescriptorType { - DescriptorType::StorageBuffer + fn descriptor_type() -> DescriptorDescTy { + DescriptorDescTy::Buffer(DescriptorBufferDesc { + dynamic: Some(false), + storage: true, + }) } } @@ -287,8 +297,15 @@ unsafe impl<'a, B, T: ?Sized + 'static> ValidParameter> for &'a pub struct CombinedImageSampler; unsafe impl DescriptorMarker for CombinedImageSampler { #[inline] - fn descriptor_type() -> DescriptorType { - DescriptorType::CombinedImageSampler + fn descriptor_type() -> DescriptorDescTy { + DescriptorDescTy::CombinedImageSampler(DescriptorImageDesc { + sampled: true, + // FIXME: correct values + dimensions: DescriptorImageDescDimensions::TwoDimensional, + multisampled: false, + array_layers: DescriptorImageDescArray::NonArrayed, + format: None, + }) } } @@ -304,8 +321,15 @@ unsafe impl<'a, I> ValidParameter for (&'a Arc, & pub struct SampledImage; unsafe impl DescriptorMarker for SampledImage { #[inline] - fn descriptor_type() -> DescriptorType { - DescriptorType::SampledImage + fn descriptor_type() -> DescriptorDescTy { + DescriptorDescTy::Image(DescriptorImageDesc { + sampled: true, + // FIXME: correct values + dimensions: DescriptorImageDescDimensions::TwoDimensional, + multisampled: false, + array_layers: DescriptorImageDescArray::NonArrayed, + format: None, + }) } } @@ -321,8 +345,9 @@ unsafe impl<'a, I> ValidParameter for &'a Arc pub struct InputAttachment; unsafe impl DescriptorMarker for InputAttachment { #[inline] - fn descriptor_type() -> DescriptorType { - DescriptorType::InputAttachment + fn descriptor_type() -> DescriptorDescTy { + // FIXME: correct values + DescriptorDescTy::InputAttachment { multisampled: false, array_layers: DescriptorImageDescArray::NonArrayed } } }