mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-27 09:14:01 +00:00
[wgsl-in] Implement WGSL interpolate
syntax from gpuweb PR #1605.
Fixes: #670
This commit is contained in:
parent
99a9e1e78e
commit
0910af2718
@ -1,7 +1,7 @@
|
|||||||
use super::{BackendResult, Error, Version, Writer};
|
use super::{BackendResult, Error, Version, Writer};
|
||||||
use crate::{
|
use crate::{
|
||||||
Binding, Bytes, Handle, ImageClass, ImageDimension, Interpolation, ScalarKind, ShaderStage,
|
Binding, Bytes, Handle, ImageClass, ImageDimension, Interpolation, Sampling, ScalarKind,
|
||||||
StorageClass, StorageFormat, Type, TypeInner,
|
ShaderStage, StorageClass, StorageFormat, Type, TypeInner,
|
||||||
};
|
};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
|
||||||
@ -289,16 +289,16 @@ impl<'a, W> Writer<'a, W> {
|
|||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(&Binding::Location {
|
if let Some(&Binding::Location {
|
||||||
interpolation: Some(interpolation),
|
interpolation,
|
||||||
|
sampling,
|
||||||
..
|
..
|
||||||
}) = binding {
|
}) = binding {
|
||||||
match interpolation {
|
if interpolation == Some(Interpolation::Linear) {
|
||||||
Interpolation::Linear => {
|
self.features.request(Features::NOPERSPECTIVE_QUALIFIER);
|
||||||
self.features.request(Features::NOPERSPECTIVE_QUALIFIER)
|
}
|
||||||
}
|
if sampling == Some(Sampling::Sample) {
|
||||||
Interpolation::Sample => self.features.request(Features::SAMPLE_QUALIFIER),
|
self.features.request(Features::SAMPLE_QUALIFIER);
|
||||||
_ => (),
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,9 +48,10 @@ use crate::{
|
|||||||
valid::{FunctionInfo, ModuleInfo},
|
valid::{FunctionInfo, ModuleInfo},
|
||||||
Arena, ArraySize, BinaryOperator, Binding, BuiltIn, Bytes, ConservativeDepth, Constant,
|
Arena, ArraySize, BinaryOperator, Binding, BuiltIn, Bytes, ConservativeDepth, Constant,
|
||||||
ConstantInner, DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle,
|
ConstantInner, DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle,
|
||||||
ImageClass, Interpolation, LocalVariable, Module, RelationalFunction, ScalarKind, ScalarValue,
|
ImageClass, Interpolation, LocalVariable, Module, RelationalFunction, Sampling, ScalarKind,
|
||||||
ShaderStage, Statement, StorageAccess, StorageClass, StorageFormat, StructMember, Type,
|
ScalarValue, ShaderStage, Statement, StorageAccess, StorageClass, StorageFormat, StructMember,
|
||||||
TypeInner, UnaryOperator,
|
Type, TypeInner, UnaryOperator,
|
||||||
|
|
||||||
};
|
};
|
||||||
use features::FeaturesManager;
|
use features::FeaturesManager;
|
||||||
use std::{
|
use std::{
|
||||||
@ -232,8 +233,10 @@ impl IdGenerator {
|
|||||||
/// Helper wrapper used to get a name for a varying
|
/// Helper wrapper used to get a name for a varying
|
||||||
///
|
///
|
||||||
/// Varying have different naming schemes depending on their binding:
|
/// Varying have different naming schemes depending on their binding:
|
||||||
/// - Varyings with builtin bindings get the from [`glsl_built_in`](glsl_built_in)
|
/// - Varyings with builtin bindings get the from [`glsl_built_in`](glsl_built_in).
|
||||||
/// - Varyings with location bindings are named `_location_X` where `X` is the location
|
/// - Varyings with location bindings are named `_S_location_X` where `S` is a
|
||||||
|
/// prefix identifying which pipeline stage the varying connects, and `X` is
|
||||||
|
/// the location.
|
||||||
struct VaryingName<'a> {
|
struct VaryingName<'a> {
|
||||||
binding: &'a Binding,
|
binding: &'a Binding,
|
||||||
stage: ShaderStage,
|
stage: ShaderStage,
|
||||||
@ -793,16 +796,22 @@ impl<'a, W: Write> Writer<'a, W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let (location, interpolation) = match binding {
|
let (location, interpolation, sampling) = match binding {
|
||||||
Some(&Binding::Location { location, interpolation }) => (location, interpolation),
|
Some(&Binding::Location { location, interpolation, sampling }) => (location, interpolation, sampling),
|
||||||
_ => return Ok(()),
|
_ => return Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Write the interpolation modifier if needed
|
// Write the interpolation modifier if needed
|
||||||
//
|
//
|
||||||
// We ignore all interpolation modifiers that aren't used in input globals in fragment
|
// We ignore all interpolation and auxiliary modifiers that aren't used in fragment
|
||||||
// shaders or output globals in vertex shaders
|
// shaders' input globals or vertex shaders' output globals.
|
||||||
|
let emit_interpolation_and_auxiliary = match self.options.shader_stage {
|
||||||
|
ShaderStage::Vertex => output,
|
||||||
|
ShaderStage::Fragment => !output,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
if let Some(interp) = interpolation {
|
if let Some(interp) = interpolation {
|
||||||
if self.options.shader_stage == ShaderStage::Fragment {
|
if emit_interpolation_and_auxiliary {
|
||||||
write!(self.out, "{} ", glsl_interpolation(interp))?;
|
write!(self.out, "{} ", glsl_interpolation(interp))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -811,13 +820,24 @@ impl<'a, W: Write> Writer<'a, W> {
|
|||||||
if self.options.version.supports_explicit_locations() {
|
if self.options.version.supports_explicit_locations() {
|
||||||
write!(
|
write!(
|
||||||
self.out,
|
self.out,
|
||||||
"layout(location = {}) {} ",
|
"layout(location = {}) ",
|
||||||
location,
|
location)?;
|
||||||
if output { "out" } else { "in" }
|
|
||||||
)?;
|
|
||||||
} else {
|
|
||||||
write!(self.out, "{} ", if output { "out" } else { "in" })?;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the sampling auxiliary qualifier.
|
||||||
|
//
|
||||||
|
// Before GLSL 4.2, the `centroid` and `sample` qualifiers were required to appear
|
||||||
|
// immediately before the `in` / `out` qualifier, so we'll just follow that rule
|
||||||
|
// here, regardless of the version.
|
||||||
|
if let Some(sampling) = sampling {
|
||||||
|
if emit_interpolation_and_auxiliary {
|
||||||
|
write!(self.out, "{} ", glsl_sampling(sampling))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the input/output qualifier.
|
||||||
|
write!(self.out, "{} ", if output { "out" } else { "in" })?;
|
||||||
|
|
||||||
// Write the type
|
// Write the type
|
||||||
// `write_type` adds no leading or trailing spaces
|
// `write_type` adds no leading or trailing spaces
|
||||||
self.write_type(ty)?;
|
self.write_type(ty)?;
|
||||||
@ -825,7 +845,7 @@ impl<'a, W: Write> Writer<'a, W> {
|
|||||||
// Finally write the global name and end the global with a `;` and a newline
|
// Finally write the global name and end the global with a `;` and a newline
|
||||||
// Leading space is important
|
// Leading space is important
|
||||||
let vname = VaryingName {
|
let vname = VaryingName {
|
||||||
binding: &Binding::Location { location, interpolation: None },
|
binding: &Binding::Location { location, interpolation: None, sampling: None },
|
||||||
stage: self.entry_point.stage,
|
stage: self.entry_point.stage,
|
||||||
output,
|
output,
|
||||||
};
|
};
|
||||||
@ -2201,8 +2221,15 @@ fn glsl_interpolation(interpolation: Interpolation) -> &'static str {
|
|||||||
Interpolation::Perspective => "smooth",
|
Interpolation::Perspective => "smooth",
|
||||||
Interpolation::Linear => "noperspective",
|
Interpolation::Linear => "noperspective",
|
||||||
Interpolation::Flat => "flat",
|
Interpolation::Flat => "flat",
|
||||||
Interpolation::Centroid => "centroid",
|
}
|
||||||
Interpolation::Sample => "sample",
|
}
|
||||||
|
|
||||||
|
/// Return the GLSL auxiliary qualifier for the given sampling value.
|
||||||
|
fn glsl_sampling(sampling: Sampling) -> &'static str {
|
||||||
|
match sampling {
|
||||||
|
Sampling::Center => "",
|
||||||
|
Sampling::Centroid => "centroid",
|
||||||
|
Sampling::Sample => "sample",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1090,17 +1090,29 @@ impl Writer {
|
|||||||
use spirv::{BuiltIn, Decoration};
|
use spirv::{BuiltIn, Decoration};
|
||||||
|
|
||||||
match *binding {
|
match *binding {
|
||||||
crate::Binding::Location { location, interpolation } => {
|
crate::Binding::Location { location, interpolation, sampling } => {
|
||||||
self.decorate(id, Decoration::Location, &[location]);
|
self.decorate(id, Decoration::Location, &[location]);
|
||||||
let interp_decoration = match interpolation {
|
|
||||||
Some(crate::Interpolation::Linear) => Some(Decoration::NoPerspective),
|
match interpolation {
|
||||||
Some(crate::Interpolation::Flat) => Some(Decoration::Flat),
|
// Perspective-correct interpolation is the default in SPIR-V.
|
||||||
Some(crate::Interpolation::Centroid) => Some(Decoration::Centroid),
|
None | Some(crate::Interpolation::Perspective) => (),
|
||||||
Some(crate::Interpolation::Sample) => Some(Decoration::Sample),
|
Some(crate::Interpolation::Flat) => {
|
||||||
Some(crate::Interpolation::Perspective) | None => None,
|
self.decorate(id, Decoration::Flat, &[]);
|
||||||
};
|
}
|
||||||
if let Some(decoration) = interp_decoration {
|
Some(crate::Interpolation::Linear) => {
|
||||||
self.decorate(id, decoration, &[]);
|
self.decorate(id, Decoration::NoPerspective, &[]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match sampling {
|
||||||
|
// Center sampling is the default in SPIR-V.
|
||||||
|
None | Some(crate::Sampling::Center) => (),
|
||||||
|
Some(crate::Sampling::Centroid) => {
|
||||||
|
self.decorate(id, Decoration::Centroid, &[]);
|
||||||
|
}
|
||||||
|
Some(crate::Sampling::Sample) => {
|
||||||
|
self.decorate(id, Decoration::Sample, &[]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::Binding::BuiltIn(built_in) => {
|
crate::Binding::BuiltIn(built_in) => {
|
||||||
|
@ -2,7 +2,8 @@ use super::{super::Typifier, constants::ConstantSolver, error::ErrorKind};
|
|||||||
use crate::{
|
use crate::{
|
||||||
proc::ResolveContext, Arena, BinaryOperator, Binding, Constant, Expression, FastHashMap,
|
proc::ResolveContext, Arena, BinaryOperator, Binding, Constant, Expression, FastHashMap,
|
||||||
Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module,
|
Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module,
|
||||||
RelationalFunction, ResourceBinding, ShaderStage, Statement, StorageClass, Type, UnaryOperator,
|
RelationalFunction, ResourceBinding, Sampling, ShaderStage, Statement, StorageClass, Type,
|
||||||
|
UnaryOperator,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -226,6 +227,7 @@ pub enum TypeQualifier {
|
|||||||
ResourceBinding(ResourceBinding),
|
ResourceBinding(ResourceBinding),
|
||||||
Binding(Binding),
|
Binding(Binding),
|
||||||
Interpolation(Interpolation),
|
Interpolation(Interpolation),
|
||||||
|
Sampling(Sampling),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -66,8 +66,8 @@ impl<'a> Iterator for Lexer<'a> {
|
|||||||
"flat" => Token::Interpolation((meta, crate::Interpolation::Flat)),
|
"flat" => Token::Interpolation((meta, crate::Interpolation::Flat)),
|
||||||
"noperspective" => Token::Interpolation((meta, crate::Interpolation::Linear)),
|
"noperspective" => Token::Interpolation((meta, crate::Interpolation::Linear)),
|
||||||
"smooth" => Token::Interpolation((meta, crate::Interpolation::Perspective)),
|
"smooth" => Token::Interpolation((meta, crate::Interpolation::Perspective)),
|
||||||
"centroid" => Token::Interpolation((meta, crate::Interpolation::Centroid)),
|
"centroid" => Token::Sampling((meta, crate::Sampling::Centroid)),
|
||||||
"sample" => Token::Interpolation((meta, crate::Interpolation::Sample)),
|
"sample" => Token::Sampling((meta, crate::Sampling::Sample)),
|
||||||
// values
|
// values
|
||||||
"true" => Token::BoolConstant((meta, true)),
|
"true" => Token::BoolConstant((meta, true)),
|
||||||
"false" => Token::BoolConstant((meta, false)),
|
"false" => Token::BoolConstant((meta, false)),
|
||||||
|
@ -10,7 +10,7 @@ pomelo! {
|
|||||||
ConstantInner, Expression,
|
ConstantInner, Expression,
|
||||||
Function, FunctionArgument, FunctionResult,
|
Function, FunctionArgument, FunctionResult,
|
||||||
GlobalVariable, Handle, Interpolation,
|
GlobalVariable, Handle, Interpolation,
|
||||||
LocalVariable, ResourceBinding, ScalarValue, ScalarKind,
|
LocalVariable, ResourceBinding, Sampling, ScalarValue, ScalarKind,
|
||||||
Statement, StorageAccess, StorageClass, StructMember,
|
Statement, StorageAccess, StorageClass, StructMember,
|
||||||
SwitchCase, Type, TypeInner, UnaryOperator,
|
SwitchCase, Type, TypeInner, UnaryOperator,
|
||||||
};
|
};
|
||||||
@ -120,6 +120,8 @@ pomelo! {
|
|||||||
%type storage_qualifier StorageQualifier;
|
%type storage_qualifier StorageQualifier;
|
||||||
%type interpolation_qualifier Interpolation;
|
%type interpolation_qualifier Interpolation;
|
||||||
%type Interpolation Interpolation;
|
%type Interpolation Interpolation;
|
||||||
|
%type sampling_qualifier Sampling;
|
||||||
|
%type Sampling Sampling;
|
||||||
|
|
||||||
// types
|
// types
|
||||||
%type fully_specified_type (Vec<TypeQualifier>, Option<Handle<Type>>);
|
%type fully_specified_type (Vec<TypeQualifier>, Option<Handle<Type>>);
|
||||||
@ -613,10 +615,15 @@ pomelo! {
|
|||||||
i
|
i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sampling_qualifier ::= Sampling((_, s)) {
|
||||||
|
s
|
||||||
|
}
|
||||||
|
|
||||||
layout_qualifier ::= Layout LeftParen layout_qualifier_id_list(l) RightParen {
|
layout_qualifier ::= Layout LeftParen layout_qualifier_id_list(l) RightParen {
|
||||||
if let Some(&(_, location)) = l.iter().find(|&q| q.0.as_str() == "location") {
|
if let Some(&(_, location)) = l.iter().find(|&q| q.0.as_str() == "location") {
|
||||||
let interpolation = None; //TODO
|
let interpolation = None; //TODO
|
||||||
StructLayout::Binding(Binding::Location { location, interpolation })
|
let sampling = None; //TODO
|
||||||
|
StructLayout::Binding(Binding::Location { location, interpolation, sampling })
|
||||||
} else if let Some(&(_, binding)) = l.iter().find(|&q| q.0.as_str() == "binding") {
|
} else if let Some(&(_, binding)) = l.iter().find(|&q| q.0.as_str() == "binding") {
|
||||||
let group = if let Some(&(_, set)) = l.iter().find(|&q| q.0.as_str() == "set") {
|
let group = if let Some(&(_, set)) = l.iter().find(|&q| q.0.as_str() == "set") {
|
||||||
set
|
set
|
||||||
@ -670,6 +677,9 @@ pomelo! {
|
|||||||
single_type_qualifier ::= interpolation_qualifier(i) {
|
single_type_qualifier ::= interpolation_qualifier(i) {
|
||||||
TypeQualifier::Interpolation(i)
|
TypeQualifier::Interpolation(i)
|
||||||
}
|
}
|
||||||
|
single_type_qualifier ::= sampling_qualifier(i) {
|
||||||
|
TypeQualifier::Sampling(i)
|
||||||
|
}
|
||||||
// single_type_qualifier ::= invariant_qualifier;
|
// single_type_qualifier ::= invariant_qualifier;
|
||||||
// single_type_qualifier ::= precise_qualifier;
|
// single_type_qualifier ::= precise_qualifier;
|
||||||
|
|
||||||
@ -1133,8 +1143,16 @@ pomelo! {
|
|||||||
let interpolation = d.type_qualifiers.iter().find_map(|tq| {
|
let interpolation = d.type_qualifiers.iter().find_map(|tq| {
|
||||||
if let TypeQualifier::Interpolation(interp) = *tq { Some(interp) } else { None }
|
if let TypeQualifier::Interpolation(interp) = *tq { Some(interp) } else { None }
|
||||||
});
|
});
|
||||||
if let Some(Binding::Location { interpolation: ref mut interp, .. }) = binding {
|
let sampling = d.type_qualifiers.iter().find_map(|tq| {
|
||||||
|
if let TypeQualifier::Sampling(samp) = *tq { Some(samp) } else { None }
|
||||||
|
});
|
||||||
|
if let Some(Binding::Location {
|
||||||
|
interpolation: ref mut interp,
|
||||||
|
sampling: ref mut samp,
|
||||||
|
..
|
||||||
|
}) = binding {
|
||||||
*interp = interpolation;
|
*interp = interpolation;
|
||||||
|
*samp = sampling;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (id, _initializer) in d.ids_initializers {
|
for (id, _initializer) in d.ids_initializers {
|
||||||
|
@ -220,6 +220,7 @@ struct Decoration {
|
|||||||
matrix_stride: Option<NonZeroU32>,
|
matrix_stride: Option<NonZeroU32>,
|
||||||
matrix_major: Option<Majority>,
|
matrix_major: Option<Majority>,
|
||||||
interpolation: Option<crate::Interpolation>,
|
interpolation: Option<crate::Interpolation>,
|
||||||
|
sampling: Option<crate::Sampling>,
|
||||||
flags: DecorationFlags,
|
flags: DecorationFlags,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,8 +254,9 @@ impl Decoration {
|
|||||||
built_in: None,
|
built_in: None,
|
||||||
location: Some(location),
|
location: Some(location),
|
||||||
interpolation,
|
interpolation,
|
||||||
|
sampling,
|
||||||
..
|
..
|
||||||
} => Ok(crate::Binding::Location { location, interpolation }),
|
} => Ok(crate::Binding::Location { location, interpolation, sampling }),
|
||||||
_ => Err(Error::MissingDecoration(spirv::Decoration::Location)),
|
_ => Err(Error::MissingDecoration(spirv::Decoration::Location)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,10 +506,10 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
|||||||
dec.interpolation = Some(crate::Interpolation::Flat);
|
dec.interpolation = Some(crate::Interpolation::Flat);
|
||||||
}
|
}
|
||||||
spirv::Decoration::Centroid => {
|
spirv::Decoration::Centroid => {
|
||||||
dec.interpolation = Some(crate::Interpolation::Centroid);
|
dec.sampling = Some(crate::Sampling::Centroid);
|
||||||
}
|
}
|
||||||
spirv::Decoration::Sample => {
|
spirv::Decoration::Sample => {
|
||||||
dec.interpolation = Some(crate::Interpolation::Sample);
|
dec.sampling = Some(crate::Sampling::Sample);
|
||||||
}
|
}
|
||||||
spirv::Decoration::NonReadable => {
|
spirv::Decoration::NonReadable => {
|
||||||
dec.flags |= DecorationFlags::NON_READABLE;
|
dec.flags |= DecorationFlags::NON_READABLE;
|
||||||
|
@ -44,13 +44,19 @@ pub fn map_interpolation(word: &str) -> Result<crate::Interpolation, Error<'_>>
|
|||||||
match word {
|
match word {
|
||||||
"linear" => Ok(crate::Interpolation::Linear),
|
"linear" => Ok(crate::Interpolation::Linear),
|
||||||
"flat" => Ok(crate::Interpolation::Flat),
|
"flat" => Ok(crate::Interpolation::Flat),
|
||||||
"centroid" => Ok(crate::Interpolation::Centroid),
|
|
||||||
"sample" => Ok(crate::Interpolation::Sample),
|
|
||||||
"perspective" => Ok(crate::Interpolation::Perspective),
|
"perspective" => Ok(crate::Interpolation::Perspective),
|
||||||
_ => Err(Error::UnknownAttribute(word)),
|
_ => Err(Error::UnknownAttribute(word)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn map_sampling(word: &str) -> Result<crate::Sampling, Error<'_>> {
|
||||||
|
match word {
|
||||||
|
"centroid" => Ok(crate::Sampling::Centroid),
|
||||||
|
"sample" => Ok(crate::Sampling::Sample),
|
||||||
|
_ => Err(Error::UnknownAttribute(word)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn map_storage_format(word: &str) -> Result<crate::StorageFormat, Error<'_>> {
|
pub fn map_storage_format(word: &str) -> Result<crate::StorageFormat, Error<'_>> {
|
||||||
use crate::StorageFormat as Sf;
|
use crate::StorageFormat as Sf;
|
||||||
Ok(match word {
|
Ok(match word {
|
||||||
|
@ -112,11 +112,12 @@ pub enum Error<'a> {
|
|||||||
ZeroSizeOrAlign,
|
ZeroSizeOrAlign,
|
||||||
#[error("not a composite type: {0:?}")]
|
#[error("not a composite type: {0:?}")]
|
||||||
NotCompositeType(Handle<crate::Type>),
|
NotCompositeType(Handle<crate::Type>),
|
||||||
#[error("Input/output binding is not consistent: location {0:?}, built-in {1:?} and interpolation {2:?}")]
|
#[error("Input/output binding is not consistent: location {0:?}, built-in {1:?}, interpolation {2:?}, and sampling {3:?}")]
|
||||||
InconsistentBinding(
|
InconsistentBinding(
|
||||||
Option<u32>,
|
Option<u32>,
|
||||||
Option<crate::BuiltIn>,
|
Option<crate::BuiltIn>,
|
||||||
Option<crate::Interpolation>,
|
Option<crate::Interpolation>,
|
||||||
|
Option<crate::Sampling>,
|
||||||
),
|
),
|
||||||
#[error("call to local `{0}(..)` can't be resolved")]
|
#[error("call to local `{0}(..)` can't be resolved")]
|
||||||
UnknownLocalFunction(&'a str),
|
UnknownLocalFunction(&'a str),
|
||||||
@ -470,6 +471,7 @@ struct BindingParser {
|
|||||||
location: Option<u32>,
|
location: Option<u32>,
|
||||||
built_in: Option<crate::BuiltIn>,
|
built_in: Option<crate::BuiltIn>,
|
||||||
interpolation: Option<crate::Interpolation>,
|
interpolation: Option<crate::Interpolation>,
|
||||||
|
sampling: Option<crate::Sampling>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BindingParser {
|
impl BindingParser {
|
||||||
@ -490,6 +492,10 @@ impl BindingParser {
|
|||||||
lexer.expect(Token::Paren('('))?;
|
lexer.expect(Token::Paren('('))?;
|
||||||
let raw = lexer.next_ident()?;
|
let raw = lexer.next_ident()?;
|
||||||
self.interpolation = Some(conv::map_interpolation(raw)?);
|
self.interpolation = Some(conv::map_interpolation(raw)?);
|
||||||
|
if lexer.skip(Token::Separator(',')) {
|
||||||
|
let raw = lexer.next_ident()?;
|
||||||
|
self.sampling = Some(conv::map_sampling(raw)?);
|
||||||
|
}
|
||||||
lexer.expect(Token::Paren(')'))?;
|
lexer.expect(Token::Paren(')'))?;
|
||||||
}
|
}
|
||||||
_ => return Err(Error::UnknownAttribute(name)),
|
_ => return Err(Error::UnknownAttribute(name)),
|
||||||
@ -498,16 +504,17 @@ impl BindingParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn finish<'a>(self) -> Result<Option<crate::Binding>, Error<'a>> {
|
fn finish<'a>(self) -> Result<Option<crate::Binding>, Error<'a>> {
|
||||||
match (self.location, self.built_in, self.interpolation) {
|
match (self.location, self.built_in, self.interpolation, self.sampling) {
|
||||||
(None, None, None) => Ok(None),
|
(None, None, None, None) => Ok(None),
|
||||||
(Some(location), None, interpolation) => {
|
(Some(location), None, interpolation, sampling) => {
|
||||||
Ok(Some(crate::Binding::Location { location, interpolation }))
|
Ok(Some(crate::Binding::Location { location, interpolation, sampling }))
|
||||||
}
|
}
|
||||||
(None, Some(bi), None) => Ok(Some(crate::Binding::BuiltIn(bi))),
|
(None, Some(bi), None, None) => Ok(Some(crate::Binding::BuiltIn(bi))),
|
||||||
(location, built_in, interpolation) => Err(Error::InconsistentBinding(
|
(location, built_in, interpolation, sampling) => Err(Error::InconsistentBinding(
|
||||||
location,
|
location,
|
||||||
built_in,
|
built_in,
|
||||||
interpolation,
|
interpolation,
|
||||||
|
sampling,
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
src/lib.rs
26
src/lib.rs
@ -226,11 +226,23 @@ pub enum Interpolation {
|
|||||||
Linear,
|
Linear,
|
||||||
/// Indicates that no interpolation will be performed.
|
/// Indicates that no interpolation will be performed.
|
||||||
Flat,
|
Flat,
|
||||||
/// When used with multi-sampling rasterization, allow
|
}
|
||||||
/// a single interpolation location for an entire pixel.
|
|
||||||
|
/// The sampling qualifiers of a binding or struct field.
|
||||||
|
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
#[cfg_attr(feature = "serialize", derive(Serialize))]
|
||||||
|
#[cfg_attr(feature = "deserialize", derive(Deserialize))]
|
||||||
|
pub enum Sampling {
|
||||||
|
/// Interpolate the value at the center of the pixel.
|
||||||
|
Center,
|
||||||
|
|
||||||
|
/// Interpolate the value at a point that lies within all samples covered by
|
||||||
|
/// the fragment within the current primitive. In multisampling, use a
|
||||||
|
/// single value for all samples in the primitive.
|
||||||
Centroid,
|
Centroid,
|
||||||
/// When used with multi-sampling rasterization, require
|
|
||||||
/// per-sample interpolation.
|
/// Interpolate the value at each sample location. In multisampling, invoke
|
||||||
|
/// the fragment shader once per sample.
|
||||||
Sample,
|
Sample,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -465,7 +477,11 @@ pub enum Binding {
|
|||||||
/// Built-in shader variable.
|
/// Built-in shader variable.
|
||||||
BuiltIn(BuiltIn),
|
BuiltIn(BuiltIn),
|
||||||
/// Indexed location.
|
/// Indexed location.
|
||||||
Location { location: u32, interpolation: Option<Interpolation> },
|
Location {
|
||||||
|
location: u32,
|
||||||
|
interpolation: Option<Interpolation>,
|
||||||
|
sampling: Option<Sampling>
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pipeline binding information for global resources.
|
/// Pipeline binding information for global resources.
|
||||||
|
@ -206,7 +206,7 @@ impl VaryingContext<'_> {
|
|||||||
return Err(VaryingError::InvalidBuiltInType(built_in));
|
return Err(VaryingError::InvalidBuiltInType(built_in));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
crate::Binding::Location { location, interpolation } => {
|
crate::Binding::Location { location, interpolation, sampling } => {
|
||||||
if !self.location_mask.insert(location as usize) {
|
if !self.location_mask.insert(location as usize) {
|
||||||
return Err(VaryingError::BindingCollision { location });
|
return Err(VaryingError::BindingCollision { location });
|
||||||
}
|
}
|
||||||
@ -218,6 +218,11 @@ impl VaryingContext<'_> {
|
|||||||
if !needs_interpolation && interpolation.is_some() {
|
if !needs_interpolation && interpolation.is_some() {
|
||||||
return Err(VaryingError::InvalidInterpolation);
|
return Err(VaryingError::InvalidInterpolation);
|
||||||
}
|
}
|
||||||
|
// It doesn't make sense to specify a sampling when
|
||||||
|
// `interpolation` is `Flat`, but SPIR-V and GLSL both
|
||||||
|
// explicitly tolerate such combinations of decorators /
|
||||||
|
// qualifiers, so we won't complain about that here.
|
||||||
|
let _ = sampling;
|
||||||
match ty_inner.scalar_kind() {
|
match ty_inner.scalar_kind() {
|
||||||
Some(crate::ScalarKind::Float) => {}
|
Some(crate::ScalarKind::Float) => {}
|
||||||
Some(_)
|
Some(_)
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
struct FragmentInput {
|
struct FragmentInput {
|
||||||
[[builtin(position)]] position: vec4<f32>;
|
[[builtin(position)]] position: vec4<f32>;
|
||||||
[[location(0), interpolate(flat)]] flat : u32;
|
[[location(0), interpolate(flat)]] flat : u32;
|
||||||
[[location(1), interpolate(linear)]] linear: f32;
|
[[location(1), interpolate(linear)]] linear : f32;
|
||||||
[[location(2), interpolate(centroid)]] centroid: vec2<f32>;
|
[[location(2), interpolate(linear,centroid)]] linear_centroid : vec2<f32>;
|
||||||
[[location(3), interpolate(sample)]] sample: vec3<f32>;
|
[[location(3), interpolate(linear,sample)]] linear_sample : vec3<f32>;
|
||||||
[[location(4), interpolate(perspective)]] perspective: vec4<f32>;
|
[[location(4), interpolate(perspective)]] perspective : vec4<f32>;
|
||||||
|
[[location(5), interpolate(perspective,centroid)]] perspective_centroid : f32;
|
||||||
|
[[location(6), interpolate(perspective,sample)]] perspective_sample : f32;
|
||||||
};
|
};
|
||||||
|
|
||||||
[[stage(vertex)]]
|
[[stage(vertex)]]
|
||||||
@ -14,9 +16,11 @@ fn main() -> FragmentInput {
|
|||||||
out.position = vec4<f32>(2.0, 4.0, 5.0, 6.0);
|
out.position = vec4<f32>(2.0, 4.0, 5.0, 6.0);
|
||||||
out.flat = 8u32;
|
out.flat = 8u32;
|
||||||
out.linear = 27.0;
|
out.linear = 27.0;
|
||||||
out.centroid = vec2<f32>(64.0, 125.0);
|
out.linear_centroid = vec2<f32>(64.0, 125.0);
|
||||||
out.sample = vec3<f32>(216.0, 343.0, 512.0);
|
out.linear_sample = vec3<f32>(216.0, 343.0, 512.0);
|
||||||
out.perspective = vec4<f32>(729.0, 1000.0, 1331.0, 1728.0);
|
out.perspective = vec4<f32>(729.0, 1000.0, 1331.0, 1728.0);
|
||||||
|
out.perspective_centroid = 2197.0;
|
||||||
|
out.perspective_sample = 2744.0;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
@ -3,19 +3,23 @@ struct FragmentInput {
|
|||||||
vec4 position;
|
vec4 position;
|
||||||
uint flat1;
|
uint flat1;
|
||||||
float linear;
|
float linear;
|
||||||
vec2 centroid1;
|
vec2 linear_centroid;
|
||||||
vec3 sample1;
|
vec3 linear_sample;
|
||||||
vec4 perspective;
|
vec4 perspective;
|
||||||
|
float perspective_centroid;
|
||||||
|
float perspective_sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
flat in uint _vs2fs_location0;
|
flat in uint _vs2fs_location0;
|
||||||
noperspective in float _vs2fs_location1;
|
noperspective in float _vs2fs_location1;
|
||||||
centroid in vec2 _vs2fs_location2;
|
noperspective centroid in vec2 _vs2fs_location2;
|
||||||
sample in vec3 _vs2fs_location3;
|
noperspective sample in vec3 _vs2fs_location3;
|
||||||
smooth in vec4 _vs2fs_location4;
|
smooth in vec4 _vs2fs_location4;
|
||||||
|
smooth centroid in float _vs2fs_location5;
|
||||||
|
smooth sample in float _vs2fs_location6;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragmentInput val = FragmentInput(gl_FragCoord, _vs2fs_location0, _vs2fs_location1, _vs2fs_location2, _vs2fs_location3, _vs2fs_location4);
|
FragmentInput val = FragmentInput(gl_FragCoord, _vs2fs_location0, _vs2fs_location1, _vs2fs_location2, _vs2fs_location3, _vs2fs_location4, _vs2fs_location5, _vs2fs_location6);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,31 +3,39 @@ struct FragmentInput {
|
|||||||
vec4 position;
|
vec4 position;
|
||||||
uint flat1;
|
uint flat1;
|
||||||
float linear;
|
float linear;
|
||||||
vec2 centroid1;
|
vec2 linear_centroid;
|
||||||
vec3 sample1;
|
vec3 linear_sample;
|
||||||
vec4 perspective;
|
vec4 perspective;
|
||||||
|
float perspective_centroid;
|
||||||
|
float perspective_sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
out uint _vs2fs_location0;
|
flat out uint _vs2fs_location0;
|
||||||
out float _vs2fs_location1;
|
noperspective out float _vs2fs_location1;
|
||||||
out vec2 _vs2fs_location2;
|
noperspective centroid out vec2 _vs2fs_location2;
|
||||||
out vec3 _vs2fs_location3;
|
noperspective sample out vec3 _vs2fs_location3;
|
||||||
out vec4 _vs2fs_location4;
|
smooth out vec4 _vs2fs_location4;
|
||||||
|
smooth centroid out float _vs2fs_location5;
|
||||||
|
smooth sample out float _vs2fs_location6;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
FragmentInput out1;
|
FragmentInput out1;
|
||||||
out1.position = vec4(2.0, 4.0, 5.0, 6.0);
|
out1.position = vec4(2.0, 4.0, 5.0, 6.0);
|
||||||
out1.flat1 = 8u;
|
out1.flat1 = 8u;
|
||||||
out1.linear = 27.0;
|
out1.linear = 27.0;
|
||||||
out1.centroid1 = vec2(64.0, 125.0);
|
out1.linear_centroid = vec2(64.0, 125.0);
|
||||||
out1.sample1 = vec3(216.0, 343.0, 512.0);
|
out1.linear_sample = vec3(216.0, 343.0, 512.0);
|
||||||
out1.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0);
|
out1.perspective = vec4(729.0, 1000.0, 1331.0, 1728.0);
|
||||||
|
out1.perspective_centroid = 2197.0;
|
||||||
|
out1.perspective_sample = 2744.0;
|
||||||
gl_Position = out1.position;
|
gl_Position = out1.position;
|
||||||
_vs2fs_location0 = out1.flat1;
|
_vs2fs_location0 = out1.flat1;
|
||||||
_vs2fs_location1 = out1.linear;
|
_vs2fs_location1 = out1.linear;
|
||||||
_vs2fs_location2 = out1.centroid1;
|
_vs2fs_location2 = out1.linear_centroid;
|
||||||
_vs2fs_location3 = out1.sample1;
|
_vs2fs_location3 = out1.linear_sample;
|
||||||
_vs2fs_location4 = out1.perspective;
|
_vs2fs_location4 = out1.perspective;
|
||||||
|
_vs2fs_location5 = out1.perspective_centroid;
|
||||||
|
_vs2fs_location6 = out1.perspective_sample;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,18 +5,22 @@ struct FragmentInput {
|
|||||||
metal::float4 position;
|
metal::float4 position;
|
||||||
metal::uint flat;
|
metal::uint flat;
|
||||||
float linear;
|
float linear;
|
||||||
metal::float2 centroid;
|
metal::float2 linear_centroid;
|
||||||
metal::float3 sample;
|
metal::float3 linear_sample;
|
||||||
metal::float4 perspective;
|
metal::float4 perspective;
|
||||||
|
float perspective_centroid;
|
||||||
|
float perspective_sample;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct main1Output {
|
struct main1Output {
|
||||||
metal::float4 position [[position]];
|
metal::float4 position [[position]];
|
||||||
metal::uint flat [[user(loc0)]];
|
metal::uint flat [[user(loc0)]];
|
||||||
float linear [[user(loc1)]];
|
float linear [[user(loc1)]];
|
||||||
metal::float2 centroid [[user(loc2)]];
|
metal::float2 linear_centroid [[user(loc2)]];
|
||||||
metal::float3 sample [[user(loc3)]];
|
metal::float3 linear_sample [[user(loc3)]];
|
||||||
metal::float4 perspective [[user(loc4)]];
|
metal::float4 perspective [[user(loc4)]];
|
||||||
|
float perspective_centroid [[user(loc5)]];
|
||||||
|
float perspective_sample [[user(loc6)]];
|
||||||
};
|
};
|
||||||
vertex main1Output main1(
|
vertex main1Output main1(
|
||||||
) {
|
) {
|
||||||
@ -24,25 +28,29 @@ vertex main1Output main1(
|
|||||||
out.position = metal::float4(2.0, 4.0, 5.0, 6.0);
|
out.position = metal::float4(2.0, 4.0, 5.0, 6.0);
|
||||||
out.flat = 8u;
|
out.flat = 8u;
|
||||||
out.linear = 27.0;
|
out.linear = 27.0;
|
||||||
out.centroid = metal::float2(64.0, 125.0);
|
out.linear_centroid = metal::float2(64.0, 125.0);
|
||||||
out.sample = metal::float3(216.0, 343.0, 512.0);
|
out.linear_sample = metal::float3(216.0, 343.0, 512.0);
|
||||||
out.perspective = metal::float4(729.0, 1000.0, 1331.0, 1728.0);
|
out.perspective = metal::float4(729.0, 1000.0, 1331.0, 1728.0);
|
||||||
|
out.perspective_centroid = 2197.0;
|
||||||
|
out.perspective_sample = 2744.0;
|
||||||
const auto _tmp = out;
|
const auto _tmp = out;
|
||||||
return main1Output { _tmp.position, _tmp.flat, _tmp.linear, _tmp.centroid, _tmp.sample, _tmp.perspective };
|
return main1Output { _tmp.position, _tmp.flat, _tmp.linear, _tmp.linear_centroid, _tmp.linear_sample, _tmp.perspective, _tmp.perspective_centroid, _tmp.perspective_sample };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct main2Input {
|
struct main2Input {
|
||||||
metal::uint flat [[user(loc0)]];
|
metal::uint flat [[user(loc0)]];
|
||||||
float linear [[user(loc1)]];
|
float linear [[user(loc1)]];
|
||||||
metal::float2 centroid [[user(loc2)]];
|
metal::float2 linear_centroid [[user(loc2)]];
|
||||||
metal::float3 sample [[user(loc3)]];
|
metal::float3 linear_sample [[user(loc3)]];
|
||||||
metal::float4 perspective [[user(loc4)]];
|
metal::float4 perspective [[user(loc4)]];
|
||||||
|
float perspective_centroid [[user(loc5)]];
|
||||||
|
float perspective_sample [[user(loc6)]];
|
||||||
};
|
};
|
||||||
fragment void main2(
|
fragment void main2(
|
||||||
main2Input varyings1 [[stage_in]]
|
main2Input varyings1 [[stage_in]]
|
||||||
, metal::float4 position [[position]]
|
, metal::float4 position [[position]]
|
||||||
) {
|
) {
|
||||||
const FragmentInput val = { position, varyings1.flat, varyings1.linear, varyings1.centroid, varyings1.sample, varyings1.perspective };
|
const FragmentInput val = { position, varyings1.flat, varyings1.linear, varyings1.linear_centroid, varyings1.linear_sample, varyings1.perspective, varyings1.perspective_centroid, varyings1.perspective_sample };
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,63 +1,83 @@
|
|||||||
; SPIR-V
|
; SPIR-V
|
||||||
; Version: 1.0
|
; Version: 1.0
|
||||||
; Generator: rspirv
|
; Generator: rspirv
|
||||||
; Bound: 95
|
; Bound: 109
|
||||||
OpCapability Shader
|
OpCapability Shader
|
||||||
OpCapability SampleRateShading
|
OpCapability SampleRateShading
|
||||||
%1 = OpExtInstImport "GLSL.std.450"
|
%1 = OpExtInstImport "GLSL.std.450"
|
||||||
OpMemoryModel Logical GLSL450
|
OpMemoryModel Logical GLSL450
|
||||||
OpEntryPoint Vertex %38 "main" %27 %29 %31 %33 %35 %37
|
OpEntryPoint Vertex %42 "main" %29 %31 %33 %35 %37 %39 %40 %41
|
||||||
OpEntryPoint Fragment %93 "main" %76 %79 %82 %85 %88 %91
|
OpEntryPoint Fragment %107 "main" %86 %89 %92 %95 %98 %101 %103 %105
|
||||||
OpExecutionMode %93 OriginUpperLeft
|
OpExecutionMode %107 OriginUpperLeft
|
||||||
OpSource GLSL 450
|
OpSource GLSL 450
|
||||||
OpName %23 "FragmentInput"
|
OpName %25 "FragmentInput"
|
||||||
OpMemberName %23 0 "position"
|
OpMemberName %25 0 "position"
|
||||||
OpMemberName %23 1 "flat"
|
OpMemberName %25 1 "flat"
|
||||||
OpMemberName %23 2 "linear"
|
OpMemberName %25 2 "linear"
|
||||||
OpMemberName %23 3 "centroid"
|
OpMemberName %25 3 "linear_centroid"
|
||||||
OpMemberName %23 4 "sample"
|
OpMemberName %25 4 "linear_sample"
|
||||||
OpMemberName %23 5 "perspective"
|
OpMemberName %25 5 "perspective"
|
||||||
OpName %24 "out"
|
OpMemberName %25 6 "perspective_centroid"
|
||||||
OpName %27 "position"
|
OpMemberName %25 7 "perspective_sample"
|
||||||
OpName %29 "flat"
|
OpName %26 "out"
|
||||||
OpName %31 "linear"
|
OpName %29 "position"
|
||||||
OpName %33 "centroid"
|
OpName %31 "flat"
|
||||||
OpName %35 "sample"
|
OpName %33 "linear"
|
||||||
OpName %37 "perspective"
|
OpName %35 "linear_centroid"
|
||||||
OpName %38 "main"
|
OpName %37 "linear_sample"
|
||||||
OpName %76 "position"
|
OpName %39 "perspective"
|
||||||
OpName %79 "flat"
|
OpName %40 "perspective_centroid"
|
||||||
OpName %82 "linear"
|
OpName %41 "perspective_sample"
|
||||||
OpName %85 "centroid"
|
OpName %42 "main"
|
||||||
OpName %88 "sample"
|
OpName %86 "position"
|
||||||
OpName %91 "perspective"
|
OpName %89 "flat"
|
||||||
OpName %93 "main"
|
OpName %92 "linear"
|
||||||
OpMemberDecorate %23 0 Offset 0
|
OpName %95 "linear_centroid"
|
||||||
OpMemberDecorate %23 1 Offset 16
|
OpName %98 "linear_sample"
|
||||||
OpMemberDecorate %23 2 Offset 20
|
OpName %101 "perspective"
|
||||||
OpMemberDecorate %23 3 Offset 24
|
OpName %103 "perspective_centroid"
|
||||||
OpMemberDecorate %23 4 Offset 32
|
OpName %105 "perspective_sample"
|
||||||
OpMemberDecorate %23 5 Offset 48
|
OpName %107 "main"
|
||||||
OpDecorate %27 BuiltIn Position
|
OpMemberDecorate %25 0 Offset 0
|
||||||
OpDecorate %29 Location 0
|
OpMemberDecorate %25 1 Offset 16
|
||||||
OpDecorate %29 Flat
|
OpMemberDecorate %25 2 Offset 20
|
||||||
OpDecorate %31 Location 1
|
OpMemberDecorate %25 3 Offset 24
|
||||||
OpDecorate %31 NoPerspective
|
OpMemberDecorate %25 4 Offset 32
|
||||||
OpDecorate %33 Location 2
|
OpMemberDecorate %25 5 Offset 48
|
||||||
OpDecorate %33 Centroid
|
OpMemberDecorate %25 6 Offset 64
|
||||||
OpDecorate %35 Location 3
|
OpMemberDecorate %25 7 Offset 68
|
||||||
OpDecorate %35 Sample
|
OpDecorate %29 BuiltIn Position
|
||||||
OpDecorate %37 Location 4
|
OpDecorate %31 Location 0
|
||||||
OpDecorate %76 BuiltIn FragCoord
|
OpDecorate %31 Flat
|
||||||
OpDecorate %79 Location 0
|
OpDecorate %33 Location 1
|
||||||
OpDecorate %79 Flat
|
OpDecorate %33 NoPerspective
|
||||||
OpDecorate %82 Location 1
|
OpDecorate %35 Location 2
|
||||||
OpDecorate %82 NoPerspective
|
OpDecorate %35 NoPerspective
|
||||||
OpDecorate %85 Location 2
|
OpDecorate %35 Centroid
|
||||||
OpDecorate %85 Centroid
|
OpDecorate %37 Location 3
|
||||||
OpDecorate %88 Location 3
|
OpDecorate %37 NoPerspective
|
||||||
OpDecorate %88 Sample
|
OpDecorate %37 Sample
|
||||||
OpDecorate %91 Location 4
|
OpDecorate %39 Location 4
|
||||||
|
OpDecorate %40 Location 5
|
||||||
|
OpDecorate %40 Centroid
|
||||||
|
OpDecorate %41 Location 6
|
||||||
|
OpDecorate %41 Sample
|
||||||
|
OpDecorate %86 BuiltIn FragCoord
|
||||||
|
OpDecorate %89 Location 0
|
||||||
|
OpDecorate %89 Flat
|
||||||
|
OpDecorate %92 Location 1
|
||||||
|
OpDecorate %92 NoPerspective
|
||||||
|
OpDecorate %95 Location 2
|
||||||
|
OpDecorate %95 NoPerspective
|
||||||
|
OpDecorate %95 Centroid
|
||||||
|
OpDecorate %98 Location 3
|
||||||
|
OpDecorate %98 NoPerspective
|
||||||
|
OpDecorate %98 Sample
|
||||||
|
OpDecorate %101 Location 4
|
||||||
|
OpDecorate %103 Location 5
|
||||||
|
OpDecorate %103 Centroid
|
||||||
|
OpDecorate %105 Location 6
|
||||||
|
OpDecorate %105 Sample
|
||||||
%2 = OpTypeVoid
|
%2 = OpTypeVoid
|
||||||
%4 = OpTypeFloat 32
|
%4 = OpTypeFloat 32
|
||||||
%3 = OpConstant %4 2.0
|
%3 = OpConstant %4 2.0
|
||||||
@ -76,97 +96,115 @@ OpDecorate %91 Location 4
|
|||||||
%17 = OpConstant %4 1000.0
|
%17 = OpConstant %4 1000.0
|
||||||
%18 = OpConstant %4 1331.0
|
%18 = OpConstant %4 1331.0
|
||||||
%19 = OpConstant %4 1728.0
|
%19 = OpConstant %4 1728.0
|
||||||
%20 = OpTypeVector %4 4
|
%20 = OpConstant %4 2197.0
|
||||||
%21 = OpTypeVector %4 2
|
%21 = OpConstant %4 2744.0
|
||||||
%22 = OpTypeVector %4 3
|
%22 = OpTypeVector %4 4
|
||||||
%23 = OpTypeStruct %20 %9 %4 %21 %22 %20
|
%23 = OpTypeVector %4 2
|
||||||
%25 = OpTypePointer Function %23
|
%24 = OpTypeVector %4 3
|
||||||
%28 = OpTypePointer Output %20
|
%25 = OpTypeStruct %22 %9 %4 %23 %24 %22 %4 %4
|
||||||
%27 = OpVariable %28 Output
|
%27 = OpTypePointer Function %25
|
||||||
%30 = OpTypePointer Output %9
|
%30 = OpTypePointer Output %22
|
||||||
%29 = OpVariable %30 Output
|
%29 = OpVariable %30 Output
|
||||||
%32 = OpTypePointer Output %4
|
%32 = OpTypePointer Output %9
|
||||||
%31 = OpVariable %32 Output
|
%31 = OpVariable %32 Output
|
||||||
%34 = OpTypePointer Output %21
|
%34 = OpTypePointer Output %4
|
||||||
%33 = OpVariable %34 Output
|
%33 = OpVariable %34 Output
|
||||||
%36 = OpTypePointer Output %22
|
%36 = OpTypePointer Output %23
|
||||||
%35 = OpVariable %36 Output
|
%35 = OpVariable %36 Output
|
||||||
%37 = OpVariable %28 Output
|
%38 = OpTypePointer Output %24
|
||||||
%39 = OpTypeFunction %2
|
%37 = OpVariable %38 Output
|
||||||
%41 = OpTypePointer Function %20
|
%39 = OpVariable %30 Output
|
||||||
%43 = OpTypeInt 32 1
|
%40 = OpVariable %34 Output
|
||||||
%44 = OpConstant %43 0
|
%41 = OpVariable %34 Output
|
||||||
%46 = OpTypePointer Function %9
|
%43 = OpTypeFunction %2
|
||||||
%47 = OpConstant %43 1
|
%45 = OpTypePointer Function %22
|
||||||
%49 = OpTypePointer Function %4
|
%47 = OpTypeInt 32 1
|
||||||
%50 = OpConstant %43 2
|
%48 = OpConstant %47 0
|
||||||
%52 = OpTypePointer Function %21
|
%50 = OpTypePointer Function %9
|
||||||
%54 = OpConstant %43 3
|
%51 = OpConstant %47 1
|
||||||
%56 = OpTypePointer Function %22
|
%53 = OpTypePointer Function %4
|
||||||
%58 = OpConstant %43 4
|
%54 = OpConstant %47 2
|
||||||
%61 = OpConstant %43 5
|
%56 = OpTypePointer Function %23
|
||||||
%66 = OpTypePointer Output %4
|
%58 = OpConstant %47 3
|
||||||
%77 = OpTypePointer Input %20
|
%60 = OpTypePointer Function %24
|
||||||
%76 = OpVariable %77 Input
|
%62 = OpConstant %47 4
|
||||||
%80 = OpTypePointer Input %9
|
%65 = OpConstant %47 5
|
||||||
%79 = OpVariable %80 Input
|
%67 = OpConstant %47 6
|
||||||
%83 = OpTypePointer Input %4
|
%69 = OpConstant %47 7
|
||||||
%82 = OpVariable %83 Input
|
%74 = OpTypePointer Output %4
|
||||||
%86 = OpTypePointer Input %21
|
%87 = OpTypePointer Input %22
|
||||||
%85 = OpVariable %86 Input
|
%86 = OpVariable %87 Input
|
||||||
%89 = OpTypePointer Input %22
|
%90 = OpTypePointer Input %9
|
||||||
%88 = OpVariable %89 Input
|
%89 = OpVariable %90 Input
|
||||||
%91 = OpVariable %77 Input
|
%93 = OpTypePointer Input %4
|
||||||
%38 = OpFunction %2 None %39
|
%92 = OpVariable %93 Input
|
||||||
%26 = OpLabel
|
%96 = OpTypePointer Input %23
|
||||||
%24 = OpVariable %25 Function
|
%95 = OpVariable %96 Input
|
||||||
OpBranch %40
|
%99 = OpTypePointer Input %24
|
||||||
%40 = OpLabel
|
%98 = OpVariable %99 Input
|
||||||
%42 = OpCompositeConstruct %20 %3 %5 %6 %7
|
%101 = OpVariable %87 Input
|
||||||
%45 = OpAccessChain %41 %24 %44
|
%103 = OpVariable %93 Input
|
||||||
OpStore %45 %42
|
%105 = OpVariable %93 Input
|
||||||
%48 = OpAccessChain %46 %24 %47
|
%42 = OpFunction %2 None %43
|
||||||
OpStore %48 %8
|
%28 = OpLabel
|
||||||
%51 = OpAccessChain %49 %24 %50
|
%26 = OpVariable %27 Function
|
||||||
OpStore %51 %10
|
OpBranch %44
|
||||||
%53 = OpCompositeConstruct %21 %11 %12
|
%44 = OpLabel
|
||||||
%55 = OpAccessChain %52 %24 %54
|
%46 = OpCompositeConstruct %22 %3 %5 %6 %7
|
||||||
OpStore %55 %53
|
%49 = OpAccessChain %45 %26 %48
|
||||||
%57 = OpCompositeConstruct %22 %13 %14 %15
|
OpStore %49 %46
|
||||||
%59 = OpAccessChain %56 %24 %58
|
%52 = OpAccessChain %50 %26 %51
|
||||||
|
OpStore %52 %8
|
||||||
|
%55 = OpAccessChain %53 %26 %54
|
||||||
|
OpStore %55 %10
|
||||||
|
%57 = OpCompositeConstruct %23 %11 %12
|
||||||
|
%59 = OpAccessChain %56 %26 %58
|
||||||
OpStore %59 %57
|
OpStore %59 %57
|
||||||
%60 = OpCompositeConstruct %20 %16 %17 %18 %19
|
%61 = OpCompositeConstruct %24 %13 %14 %15
|
||||||
%62 = OpAccessChain %41 %24 %61
|
%63 = OpAccessChain %60 %26 %62
|
||||||
OpStore %62 %60
|
OpStore %63 %61
|
||||||
%63 = OpLoad %23 %24
|
%64 = OpCompositeConstruct %22 %16 %17 %18 %19
|
||||||
%64 = OpCompositeExtract %20 %63 0
|
%66 = OpAccessChain %45 %26 %65
|
||||||
OpStore %27 %64
|
OpStore %66 %64
|
||||||
%65 = OpAccessChain %66 %27 %47
|
%68 = OpAccessChain %53 %26 %67
|
||||||
%67 = OpLoad %4 %65
|
OpStore %68 %20
|
||||||
%68 = OpFNegate %4 %67
|
%70 = OpAccessChain %53 %26 %69
|
||||||
OpStore %65 %68
|
OpStore %70 %21
|
||||||
%69 = OpCompositeExtract %9 %63 1
|
%71 = OpLoad %25 %26
|
||||||
OpStore %29 %69
|
%72 = OpCompositeExtract %22 %71 0
|
||||||
%70 = OpCompositeExtract %4 %63 2
|
OpStore %29 %72
|
||||||
OpStore %31 %70
|
%73 = OpAccessChain %74 %29 %51
|
||||||
%71 = OpCompositeExtract %21 %63 3
|
%75 = OpLoad %4 %73
|
||||||
OpStore %33 %71
|
%76 = OpFNegate %4 %75
|
||||||
%72 = OpCompositeExtract %22 %63 4
|
OpStore %73 %76
|
||||||
OpStore %35 %72
|
%77 = OpCompositeExtract %9 %71 1
|
||||||
%73 = OpCompositeExtract %20 %63 5
|
OpStore %31 %77
|
||||||
OpStore %37 %73
|
%78 = OpCompositeExtract %4 %71 2
|
||||||
|
OpStore %33 %78
|
||||||
|
%79 = OpCompositeExtract %23 %71 3
|
||||||
|
OpStore %35 %79
|
||||||
|
%80 = OpCompositeExtract %24 %71 4
|
||||||
|
OpStore %37 %80
|
||||||
|
%81 = OpCompositeExtract %22 %71 5
|
||||||
|
OpStore %39 %81
|
||||||
|
%82 = OpCompositeExtract %4 %71 6
|
||||||
|
OpStore %40 %82
|
||||||
|
%83 = OpCompositeExtract %4 %71 7
|
||||||
|
OpStore %41 %83
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
||||||
%93 = OpFunction %2 None %39
|
%107 = OpFunction %2 None %43
|
||||||
%74 = OpLabel
|
%84 = OpLabel
|
||||||
%78 = OpLoad %20 %76
|
%88 = OpLoad %22 %86
|
||||||
%81 = OpLoad %9 %79
|
%91 = OpLoad %9 %89
|
||||||
%84 = OpLoad %4 %82
|
%94 = OpLoad %4 %92
|
||||||
%87 = OpLoad %21 %85
|
%97 = OpLoad %23 %95
|
||||||
%90 = OpLoad %22 %88
|
%100 = OpLoad %24 %98
|
||||||
%92 = OpLoad %20 %91
|
%102 = OpLoad %22 %101
|
||||||
%75 = OpCompositeConstruct %23 %78 %81 %84 %87 %90 %92
|
%104 = OpLoad %4 %103
|
||||||
OpBranch %94
|
%106 = OpLoad %4 %105
|
||||||
%94 = OpLabel
|
%85 = OpCompositeConstruct %25 %88 %91 %94 %97 %100 %102 %104 %106
|
||||||
|
OpBranch %108
|
||||||
|
%108 = OpLabel
|
||||||
OpReturn
|
OpReturn
|
||||||
OpFunctionEnd
|
OpFunctionEnd
|
@ -1520,6 +1520,7 @@
|
|||||||
binding: Some(Location(
|
binding: Some(Location(
|
||||||
location: 0,
|
location: 0,
|
||||||
interpolation: Some(Perspective),
|
interpolation: Some(Perspective),
|
||||||
|
sampling: None,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -1528,6 +1529,7 @@
|
|||||||
binding: Some(Location(
|
binding: Some(Location(
|
||||||
location: 1,
|
location: 1,
|
||||||
interpolation: Some(Perspective),
|
interpolation: Some(Perspective),
|
||||||
|
sampling: None,
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -1536,6 +1538,7 @@
|
|||||||
binding: Some(Location(
|
binding: Some(Location(
|
||||||
location: 0,
|
location: 0,
|
||||||
interpolation: None,
|
interpolation: None,
|
||||||
|
sampling: None,
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
local_variables: [],
|
local_variables: [],
|
||||||
|
Loading…
Reference in New Issue
Block a user