Skip to content

Commit

Permalink
implement invariant attribute
Browse files Browse the repository at this point in the history
  • Loading branch information
teoxoy committed Mar 23, 2022
1 parent 05f050f commit c19e9de
Show file tree
Hide file tree
Showing 37 changed files with 329 additions and 130 deletions.
2 changes: 1 addition & 1 deletion src/back/glsl/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ impl<'a, W> Writer<'a, W> {
_ => {
if let Some(binding) = binding {
match *binding {
Binding::BuiltIn(builtin) => match builtin {
Binding::BuiltIn { built_in, .. } => match built_in {
crate::BuiltIn::ClipDistance => {
self.features.request(Features::CLIP_DISTANCE)
}
Expand Down
15 changes: 12 additions & 3 deletions src/back/glsl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ impl fmt::Display for VaryingName<'_> {
};
write!(f, "_{}_location{}", prefix, location,)
}
crate::Binding::BuiltIn(built_in) => {
crate::Binding::BuiltIn { built_in, .. } => {
write!(f, "{}", glsl_built_in(built_in, self.output))
}
}
Expand Down Expand Up @@ -1122,6 +1122,13 @@ impl<'a, W: Write> Writer<'a, W> {
interpolation,
sampling,
}) => (location, interpolation, sampling),
Some(&crate::Binding::BuiltIn {
built_in,
invariant: true,
}) => {
writeln!(self.out, "invariant {};", glsl_built_in(built_in, output))?;
return Ok(());
}
_ => return Ok(()),
};

Expand Down Expand Up @@ -1772,8 +1779,10 @@ impl<'a, W: Write> Writer<'a, W> {

for (index, member) in members.iter().enumerate() {
// TODO: handle builtin in better way
if let Some(crate::Binding::BuiltIn(builtin)) =
member.binding
if let Some(crate::Binding::BuiltIn {
built_in: builtin,
..
}) = member.binding
{
match builtin {
crate::BuiltIn::ClipDistance
Expand Down
72 changes: 54 additions & 18 deletions src/back/hlsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl InterfaceKey {
fn new(binding: Option<&crate::Binding>) -> Self {
match binding {
Some(&crate::Binding::Location { location, .. }) => Self::Location(location),
Some(&crate::Binding::BuiltIn(bi)) => Self::BuiltIn(bi),
Some(&crate::Binding::BuiltIn { built_in, .. }) => Self::BuiltIn(built_in),
None => Self::Other,
}
}
Expand Down Expand Up @@ -301,6 +301,34 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
Ok(super::ReflectionInfo { entry_point_names })
}

fn write_modifier(&mut self, binding: &crate::Binding) -> BackendResult {
match *binding {
crate::Binding::BuiltIn {
invariant: true, ..
} => {
write!(self.out, "precise ")?;
}
crate::Binding::Location {
interpolation,
sampling,
..
} => {
if let Some(interpolation) = interpolation {
write!(self.out, "{} ", interpolation.to_hlsl_str())?
}

if let Some(sampling) = sampling {
if let Some(string) = sampling.to_hlsl_str() {
write!(self.out, "{} ", string)?
}
}
}
_ => {}
}

Ok(())
}

//TODO: we could force fragment outputs to always go through `entry_point_io.output` path
// if they are struct, so that the `stage` argument here could be omitted.
fn write_semantic(
Expand All @@ -309,7 +337,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
stage: Option<(ShaderStage, Io)>,
) -> BackendResult {
match *binding {
crate::Binding::BuiltIn(builtin) => {
crate::Binding::BuiltIn {
built_in: builtin, ..
} => {
let builtin_str = builtin.to_hlsl_str()?;
write!(self.out, " : {}", builtin_str)?;
}
Expand Down Expand Up @@ -341,6 +371,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
writeln!(self.out, " {{")?;
for m in members.iter() {
write!(self.out, "{}", back::INDENT)?;
if let Some(ref binding) = m.binding {
self.write_modifier(binding)?;
}
self.write_type(module, m.ty)?;
write!(self.out, " {}", &m.name)?;
if let Some(ref binding) = m.binding {
Expand Down Expand Up @@ -750,22 +783,9 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
self.write_array_size(module, size)?;
}
_ => {
// Write interpolation modifier before type
if let Some(crate::Binding::Location {
interpolation,
sampling,
..
}) = member.binding
{
if let Some(interpolation) = interpolation {
write!(self.out, "{} ", interpolation.to_hlsl_str())?
}

if let Some(sampling) = sampling {
if let Some(string) = sampling.to_hlsl_str() {
write!(self.out, "{} ", string)?
}
}
// Write modifier before type
if let Some(ref binding) = member.binding {
self.write_modifier(binding)?;
}

if let TypeInner::Matrix { .. } = module.types[member.ty].inner {
Expand Down Expand Up @@ -885,6 +905,22 @@ impl<'a, W: fmt::Write> super::Writer<'a, W> {
func_ctx: &back::FunctionCtx<'_>,
) -> BackendResult {
// Function Declaration Syntax - https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/dx-graphics-hlsl-function-syntax

// Write modifier
if let Some(crate::FunctionResult {
binding:
Some(
ref binding @ crate::Binding::BuiltIn {
invariant: true, ..
},
),
..
}) = func.result
{
self.write_modifier(binding)?;
}

// Write return type
if let Some(ref result) = func.result {
match func_ctx.ty {
back::FunctionType::Function(_) => {
Expand Down
4 changes: 2 additions & 2 deletions src/back/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,14 @@ impl<'a> FunctionCtx<'_> {
match self.expressions[expression] {
crate::Expression::FunctionArgument(arg_index) => {
return match ep_function.arguments[arg_index as usize].binding {
Some(crate::Binding::BuiltIn(bi)) => Some(bi),
Some(crate::Binding::BuiltIn { built_in: bi, .. }) => Some(bi),
_ => built_in,
};
}
crate::Expression::AccessIndex { base, index } => {
match *self.info[base].ty.inner_with(&module.types) {
crate::TypeInner::Struct { ref members, .. } => {
if let Some(crate::Binding::BuiltIn(bi)) =
if let Some(crate::Binding::BuiltIn { built_in: bi, .. }) =
members[index as usize].binding
{
built_in = Some(bi);
Expand Down
37 changes: 28 additions & 9 deletions src/back/msl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ impl ops::Index<crate::ShaderStage> for PerStageMap {
}

enum ResolvedBinding {
BuiltIn(crate::BuiltIn),
BuiltIn {
built_in: crate::BuiltIn,
invariant: bool,
},
Attribute(u32),
Color(u32),
User {
Expand Down Expand Up @@ -146,6 +149,8 @@ pub enum Error {
CapabilityNotSupported(crate::valid::Capabilities),
#[error("address space {0:?} is not supported for target MSL version")]
UnsupportedAddressSpace(crate::AddressSpace),
#[error("attribute '{0}' is not supported for target MSL version")]
UnsupportedAttribute(String),
}

#[derive(Clone, Debug, PartialEq, thiserror::Error)]
Expand Down Expand Up @@ -218,7 +223,19 @@ impl Options {
mode: LocationMode,
) -> Result<ResolvedBinding, Error> {
match *binding {
crate::Binding::BuiltIn(built_in) => Ok(ResolvedBinding::BuiltIn(built_in)),
crate::Binding::BuiltIn {
built_in,
invariant,
} => {
if invariant && self.lang_version < (2, 1) {
return Err(Error::UnsupportedAttribute("invariant".to_string()));
}

Ok(ResolvedBinding::BuiltIn {
built_in,
invariant,
})
}
crate::Binding::Location {
location,
interpolation,
Expand Down Expand Up @@ -328,8 +345,12 @@ impl ResolvedBinding {
}

fn try_fmt<W: Write>(&self, out: &mut W) -> Result<(), Error> {
write!(out, " [[")?;
match *self {
Self::BuiltIn(built_in) => {
Self::BuiltIn {
built_in,
invariant,
} => {
use crate::BuiltIn as Bi;
let name = match built_in {
Bi::Position => "position",
Expand Down Expand Up @@ -358,6 +379,10 @@ impl ResolvedBinding {
}
};
write!(out, "{}", name)?;

if invariant {
write!(out, ", invariant")?;
}
}
Self::Attribute(index) => write!(out, "attribute({})", index)?,
Self::Color(index) => write!(out, "color({})", index)?,
Expand All @@ -384,12 +409,6 @@ impl ResolvedBinding {
}
}
}
Ok(())
}

fn try_fmt_decorated<W: Write>(&self, out: &mut W) -> Result<(), Error> {
write!(out, " [[")?;
self.try_fmt(out)?;
write!(out, "]]")?;
Ok(())
}
Expand Down
42 changes: 25 additions & 17 deletions src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2106,13 +2106,19 @@ impl<W: Write> Writer<W> {

for (index, member) in members.iter().enumerate() {
match member.binding {
Some(crate::Binding::BuiltIn(crate::BuiltIn::PointSize)) => {
Some(crate::Binding::BuiltIn {
built_in: crate::BuiltIn::PointSize,
..
}) => {
has_point_size = true;
if !context.pipeline_options.allow_point_size {
continue;
}
}
Some(crate::Binding::BuiltIn(crate::BuiltIn::CullDistance)) => {
Some(crate::Binding::BuiltIn {
built_in: crate::BuiltIn::CullDistance,
..
}) => {
log::warn!("Ignoring CullDistance built-in");
continue;
}
Expand Down Expand Up @@ -3355,7 +3361,7 @@ impl<W: Write> Writer<W> {
};
let resolved = options.resolve_local_binding(binding, in_mode)?;
write!(self.out, "{}{} {}", back::INDENT, ty_name, name)?;
resolved.try_fmt_decorated(&mut self.out)?;
resolved.try_fmt(&mut self.out)?;
writeln!(self.out, ";")?;
}
writeln!(self.out, "}};")?;
Expand Down Expand Up @@ -3401,7 +3407,10 @@ impl<W: Write> Writer<W> {
match *binding {
// Point size is only supported in VS of pipelines with
// point primitive topology.
crate::Binding::BuiltIn(crate::BuiltIn::PointSize) => {
crate::Binding::BuiltIn {
built_in: crate::BuiltIn::PointSize,
..
} => {
has_point_size = true;
if !pipeline_options.allow_point_size {
continue;
Expand All @@ -3411,7 +3420,10 @@ impl<W: Write> Writer<W> {
// But we can't return UnsupportedBuiltIn error to user.
// Because otherwise we can't generate msl shader from any glslang SPIR-V shaders.
// glslang generates gl_PerVertex struct with gl_CullDistance builtin inside by default.
crate::Binding::BuiltIn(crate::BuiltIn::CullDistance) => {
crate::Binding::BuiltIn {
built_in: crate::BuiltIn::CullDistance,
..
} => {
log::warn!("Ignoring CullDistance BuiltIn");
continue;
}
Expand All @@ -3430,14 +3442,8 @@ impl<W: Write> Writer<W> {
if let Some(array_len) = array_len {
write!(self.out, " [{}]", array_len)?;
}
write!(self.out, " [[")?;
resolved.try_fmt(&mut self.out)?;
if options.lang_version >= (2, 1)
&& *binding == crate::Binding::BuiltIn(crate::BuiltIn::Position)
{
write!(self.out, ", invariant")?;
}
writeln!(self.out, "]];")?;
writeln!(self.out, ";")?;
}

if pipeline_options.allow_point_size
Expand Down Expand Up @@ -3483,7 +3489,7 @@ impl<W: Write> Writer<W> {
let mut flattened_member_names = FastHashMap::default();
for &(ref name_key, ty, binding) in flattened_arguments.iter() {
let binding = match binding {
Some(ref binding @ &crate::Binding::BuiltIn(..)) => binding,
Some(ref binding @ &crate::Binding::BuiltIn { .. }) => binding,
_ => continue,
};
let name = if let NameKey::StructMember(ty, index) = *name_key {
Expand Down Expand Up @@ -3511,7 +3517,7 @@ impl<W: Write> Writer<W> {
','
};
write!(self.out, "{} {} {}", separator, ty_name, name)?;
resolved.try_fmt_decorated(&mut self.out)?;
resolved.try_fmt(&mut self.out)?;
writeln!(self.out)?;
}

Expand Down Expand Up @@ -3560,7 +3566,7 @@ impl<W: Write> Writer<W> {
write!(self.out, "{} ", separator)?;
tyvar.try_fmt(&mut self.out)?;
if let Some(resolved) = resolved {
resolved.try_fmt_decorated(&mut self.out)?;
resolved.try_fmt(&mut self.out)?;
}
if let Some(value) = var.init {
let coco = ConstantContext {
Expand Down Expand Up @@ -3589,7 +3595,7 @@ impl<W: Write> Writer<W> {
"{} constant _mslBufferSizes& _buffer_sizes",
separator,
)?;
resolved.try_fmt_decorated(&mut self.out)?;
resolved.try_fmt(&mut self.out)?;
writeln!(self.out)?;
}

Expand Down Expand Up @@ -3674,7 +3680,9 @@ impl<W: Write> Writer<W> {
// have passed it as its own argument and assigned
// it a new name.
let name = match member.binding {
Some(crate::Binding::BuiltIn(_)) => &flattened_member_names[&key],
Some(crate::Binding::BuiltIn { .. }) => {
&flattened_member_names[&key]
}
_ => &self.names[&key],
};
if member_index != 0 {
Expand Down
2 changes: 1 addition & 1 deletion src/back/spv/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ pub(super) fn contains_builtin(
arena: &UniqueArena<crate::Type>,
built_in: crate::BuiltIn,
) -> bool {
if let Some(&crate::Binding::BuiltIn(bi)) = binding {
if let Some(&crate::Binding::BuiltIn { built_in: bi, .. }) = binding {
bi == built_in
} else if let crate::TypeInner::Struct { ref members, .. } = arena[ty].inner {
members
Expand Down
Loading

0 comments on commit c19e9de

Please sign in to comment.