diff --git a/src/back/glsl/mod.rs b/src/back/glsl/mod.rs index a8c41faf85..ddb1c6c6c0 100644 --- a/src/back/glsl/mod.rs +++ b/src/back/glsl/mod.rs @@ -1686,18 +1686,23 @@ fn glsl_scalar(kind: ScalarKind, width: crate::Bytes) -> Result &'static str { match built_in { + // vertex BuiltIn::Position => "gl_Position", - BuiltIn::GlobalInvocationId => "gl_GlobalInvocationID", BuiltIn::BaseInstance => "gl_BaseInstance", BuiltIn::BaseVertex => "gl_BaseVertex", BuiltIn::ClipDistance => "gl_ClipDistance", BuiltIn::InstanceIndex => "gl_InstanceID", - BuiltIn::VertexIndex => "gl_VertexID", BuiltIn::PointSize => "gl_PointSize", + BuiltIn::VertexIndex => "gl_VertexID", + // fragment BuiltIn::FragCoord => "gl_FragCoord", + BuiltIn::FragDepth => "gl_FragDepth", BuiltIn::FrontFacing => "gl_FrontFacing", BuiltIn::SampleIndex => "gl_SampleID", - BuiltIn::FragDepth => "gl_FragDepth", + BuiltIn::SampleMaskIn => "gl_SampleMaskIn", + BuiltIn::SampleMaskOut => "gl_SampleMask", + // compute + BuiltIn::GlobalInvocationId => "gl_GlobalInvocationID", BuiltIn::LocalInvocationId => "gl_LocalInvocationID", BuiltIn::LocalInvocationIndex => "gl_LocalInvocationIndex", BuiltIn::WorkGroupId => "gl_WorkGroupID", diff --git a/src/back/msl/mod.rs b/src/back/msl/mod.rs index 053704303f..53c8ddf38c 100644 --- a/src/back/msl/mod.rs +++ b/src/back/msl/mod.rs @@ -173,6 +173,8 @@ impl ResolvedBinding { Bi::FragDepth => "depth(any)", Bi::FrontFacing => "front_facing", Bi::SampleIndex => "sample_id", + Bi::SampleMaskIn => "sample_mask", + Bi::SampleMaskOut => "sample_mask", // compute Bi::GlobalInvocationId => "thread_position_in_grid", Bi::LocalInvocationId => "thread_position_in_threadgroup", diff --git a/src/back/spv/writer.rs b/src/back/spv/writer.rs index bd4fbac0e3..8f9d3ef93a 100644 --- a/src/back/spv/writer.rs +++ b/src/back/spv/writer.rs @@ -856,23 +856,28 @@ impl Writer { )); } Some(crate::Binding::BuiltIn(built_in)) => { + use crate::BuiltIn as Bi; let built_in = match built_in { - crate::BuiltIn::BaseInstance => spirv::BuiltIn::BaseInstance, - crate::BuiltIn::BaseVertex => spirv::BuiltIn::BaseVertex, - crate::BuiltIn::ClipDistance => spirv::BuiltIn::ClipDistance, - crate::BuiltIn::InstanceIndex => spirv::BuiltIn::InstanceIndex, - crate::BuiltIn::Position => spirv::BuiltIn::Position, - crate::BuiltIn::VertexIndex => spirv::BuiltIn::VertexIndex, - crate::BuiltIn::PointSize => spirv::BuiltIn::PointSize, - crate::BuiltIn::FragCoord => spirv::BuiltIn::FragCoord, - crate::BuiltIn::FrontFacing => spirv::BuiltIn::FrontFacing, - crate::BuiltIn::SampleIndex => spirv::BuiltIn::SampleId, - crate::BuiltIn::FragDepth => spirv::BuiltIn::FragDepth, - crate::BuiltIn::GlobalInvocationId => spirv::BuiltIn::GlobalInvocationId, - crate::BuiltIn::LocalInvocationId => spirv::BuiltIn::LocalInvocationId, - crate::BuiltIn::LocalInvocationIndex => spirv::BuiltIn::LocalInvocationIndex, - crate::BuiltIn::WorkGroupId => spirv::BuiltIn::WorkgroupId, - crate::BuiltIn::WorkGroupSize => spirv::BuiltIn::WorkgroupSize, + Bi::BaseInstance => spirv::BuiltIn::BaseInstance, + Bi::BaseVertex => spirv::BuiltIn::BaseVertex, + Bi::ClipDistance => spirv::BuiltIn::ClipDistance, + Bi::InstanceIndex => spirv::BuiltIn::InstanceIndex, + Bi::PointSize => spirv::BuiltIn::PointSize, + Bi::Position => spirv::BuiltIn::Position, + Bi::VertexIndex => spirv::BuiltIn::VertexIndex, + // fragment + Bi::FragCoord => spirv::BuiltIn::FragCoord, + Bi::FragDepth => spirv::BuiltIn::FragDepth, + Bi::FrontFacing => spirv::BuiltIn::FrontFacing, + Bi::SampleIndex => spirv::BuiltIn::SampleId, + Bi::SampleMaskIn => spirv::BuiltIn::SampleMask, + Bi::SampleMaskOut => spirv::BuiltIn::SampleMask, + // compute + Bi::GlobalInvocationId => spirv::BuiltIn::GlobalInvocationId, + Bi::LocalInvocationId => spirv::BuiltIn::LocalInvocationId, + Bi::LocalInvocationIndex => spirv::BuiltIn::LocalInvocationIndex, + Bi::WorkGroupId => spirv::BuiltIn::WorkgroupId, + Bi::WorkGroupSize => spirv::BuiltIn::WorkgroupSize, }; self.annotations diff --git a/src/front/spv/convert.rs b/src/front/spv/convert.rs index 167863efa3..e2259aa4e4 100644 --- a/src/front/spv/convert.rs +++ b/src/front/spv/convert.rs @@ -98,21 +98,28 @@ pub fn map_width(word: spirv::Word) -> Result { .map_err(|_| Error::InvalidTypeWidth(word)) } -pub fn map_builtin(word: spirv::Word) -> Result { +pub fn map_builtin(word: spirv::Word, is_output: bool) -> Result { use spirv::BuiltIn as Bi; Ok(match spirv::BuiltIn::from_u32(word) { Some(Bi::BaseInstance) => crate::BuiltIn::BaseInstance, Some(Bi::BaseVertex) => crate::BuiltIn::BaseVertex, Some(Bi::ClipDistance) => crate::BuiltIn::ClipDistance, Some(Bi::InstanceIndex) => crate::BuiltIn::InstanceIndex, + Some(Bi::PointSize) => crate::BuiltIn::PointSize, Some(Bi::Position) => crate::BuiltIn::Position, Some(Bi::VertexIndex) => crate::BuiltIn::VertexIndex, // fragment - Some(Bi::PointSize) => crate::BuiltIn::PointSize, Some(Bi::FragCoord) => crate::BuiltIn::FragCoord, + Some(Bi::FragDepth) => crate::BuiltIn::FragDepth, Some(Bi::FrontFacing) => crate::BuiltIn::FrontFacing, Some(Bi::SampleId) => crate::BuiltIn::SampleIndex, - Some(Bi::FragDepth) => crate::BuiltIn::FragDepth, + Some(Bi::SampleMask) => { + if is_output { + crate::BuiltIn::SampleMaskOut + } else { + crate::BuiltIn::SampleMaskIn + } + } // compute Some(Bi::GlobalInvocationId) => crate::BuiltIn::GlobalInvocationId, Some(Bi::LocalInvocationId) => crate::BuiltIn::LocalInvocationId, diff --git a/src/front/spv/mod.rs b/src/front/spv/mod.rs index d69b431d0c..fc07e58b4e 100644 --- a/src/front/spv/mod.rs +++ b/src/front/spv/mod.rs @@ -158,7 +158,7 @@ bitflags::bitflags! { #[derive(Debug, Default)] struct Decoration { name: Option, - built_in: Option, + built_in: Option, location: Option, desc_set: Option, desc_index: Option, @@ -177,7 +177,7 @@ impl Decoration { } } - fn get_binding(&self) -> Option { + fn get_binding(&self, is_output: bool) -> Option { //TODO: validate this better match *self { Decoration { @@ -186,7 +186,13 @@ impl Decoration { desc_set: None, desc_index: None, .. - } => Some(crate::Binding::BuiltIn(built_in)), + } => match convert::map_builtin(built_in, is_output) { + Ok(built_in) => Some(crate::Binding::BuiltIn(built_in)), + Err(e) => { + log::warn!("{:?}", e); + None + } + }, Decoration { built_in: None, location: Some(loc), @@ -381,11 +387,7 @@ impl> Parser { match dec_typed { spirv::Decoration::BuiltIn => { inst.expect(base_words + 2)?; - let raw = self.next()?; - match map_builtin(raw) { - Ok(built_in) => dec.built_in = Some(built_in), - Err(_e) => log::warn!("Unsupported builtin {}", raw), - }; + dec.built_in = Some(self.next()?); } spirv::Decoration::Location => { inst.expect(base_words + 2)?; @@ -2345,7 +2347,7 @@ impl> Parser { crate::StorageAccess::empty() }; - let binding = dec.get_binding(); + let binding = dec.get_binding(class == crate::StorageClass::Output); let ty = match binding { // SPIR-V only cares about some of the built-in types being integer. // Naga requires them to be strictly unsigned, so we have to patch it. diff --git a/src/front/wgsl/conv.rs b/src/front/wgsl/conv.rs index d10a3afcd0..8aa0d52383 100644 --- a/src/front/wgsl/conv.rs +++ b/src/front/wgsl/conv.rs @@ -21,6 +21,9 @@ pub fn map_built_in(word: &str) -> Result> { "front_facing" => crate::BuiltIn::FrontFacing, "frag_coord" => crate::BuiltIn::FragCoord, "frag_depth" => crate::BuiltIn::FragDepth, + "sample_index" => crate::BuiltIn::SampleIndex, + "sample_mask_in" => crate::BuiltIn::SampleMaskIn, + "sample_mask_out" => crate::BuiltIn::SampleMaskOut, // compute "global_invocation_id" => crate::BuiltIn::GlobalInvocationId, "local_invocation_id" => crate::BuiltIn::LocalInvocationId, diff --git a/src/lib.rs b/src/lib.rs index 2719c40ccb..b002ac82d5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -140,14 +140,16 @@ pub enum BuiltIn { BaseVertex, ClipDistance, InstanceIndex, + PointSize, Position, VertexIndex, // fragment - PointSize, FragCoord, + FragDepth, FrontFacing, SampleIndex, - FragDepth, + SampleMaskIn, + SampleMaskOut, // compute GlobalInvocationId, LocalInvocationId, diff --git a/src/proc/validator.rs b/src/proc/validator.rs index 14de47ff76..619f1f349a 100644 --- a/src/proc/validator.rs +++ b/src/proc/validator.rs @@ -158,6 +158,8 @@ impl crate::GlobalVariable { | Bi::InstanceIndex | Bi::VertexIndex | Bi::SampleIndex + | Bi::SampleMaskIn + | Bi::SampleMaskOut | Bi::LocalInvocationIndex => Ti::Scalar { kind: Sk::Uint, width, @@ -500,10 +502,10 @@ impl Validator { | (crate::ShaderStage::Vertex, crate::BuiltIn::BaseVertex) | (crate::ShaderStage::Vertex, crate::BuiltIn::InstanceIndex) | (crate::ShaderStage::Vertex, crate::BuiltIn::VertexIndex) - | (crate::ShaderStage::Fragment, crate::BuiltIn::PointSize) | (crate::ShaderStage::Fragment, crate::BuiltIn::FragCoord) | (crate::ShaderStage::Fragment, crate::BuiltIn::FrontFacing) | (crate::ShaderStage::Fragment, crate::BuiltIn::SampleIndex) + | (crate::ShaderStage::Fragment, crate::BuiltIn::SampleMaskIn) | (crate::ShaderStage::Compute, crate::BuiltIn::GlobalInvocationId) | (crate::ShaderStage::Compute, crate::BuiltIn::LocalInvocationId) | (crate::ShaderStage::Compute, crate::BuiltIn::LocalInvocationIndex) @@ -527,7 +529,8 @@ impl Validator { (crate::ShaderStage::Vertex, crate::BuiltIn::Position) | (crate::ShaderStage::Vertex, crate::BuiltIn::PointSize) | (crate::ShaderStage::Vertex, crate::BuiltIn::ClipDistance) - | (crate::ShaderStage::Fragment, crate::BuiltIn::FragDepth) => (), + | (crate::ShaderStage::Fragment, crate::BuiltIn::FragDepth) + | (crate::ShaderStage::Fragment, crate::BuiltIn::SampleMaskOut) => (), _ => return Err(EntryPointError::InvalidBuiltIn(built_in)), }, Some(crate::Binding::Location(loc)) => {