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 crate::{
|
||||
Binding, Bytes, Handle, ImageClass, ImageDimension, Interpolation, ScalarKind, ShaderStage,
|
||||
StorageClass, StorageFormat, Type, TypeInner,
|
||||
Binding, Bytes, Handle, ImageClass, ImageDimension, Interpolation, Sampling, ScalarKind,
|
||||
ShaderStage, StorageClass, StorageFormat, Type, TypeInner,
|
||||
};
|
||||
use std::io::Write;
|
||||
|
||||
@ -289,16 +289,16 @@ impl<'a, W> Writer<'a, W> {
|
||||
}
|
||||
_ => {
|
||||
if let Some(&Binding::Location {
|
||||
interpolation: Some(interpolation),
|
||||
interpolation,
|
||||
sampling,
|
||||
..
|
||||
}) = binding {
|
||||
match interpolation {
|
||||
Interpolation::Linear => {
|
||||
self.features.request(Features::NOPERSPECTIVE_QUALIFIER)
|
||||
}
|
||||
Interpolation::Sample => self.features.request(Features::SAMPLE_QUALIFIER),
|
||||
_ => (),
|
||||
};
|
||||
if interpolation == Some(Interpolation::Linear) {
|
||||
self.features.request(Features::NOPERSPECTIVE_QUALIFIER);
|
||||
}
|
||||
if sampling == Some(Sampling::Sample) {
|
||||
self.features.request(Features::SAMPLE_QUALIFIER);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,9 +48,10 @@ use crate::{
|
||||
valid::{FunctionInfo, ModuleInfo},
|
||||
Arena, ArraySize, BinaryOperator, Binding, BuiltIn, Bytes, ConservativeDepth, Constant,
|
||||
ConstantInner, DerivativeAxis, Expression, FastHashMap, Function, GlobalVariable, Handle,
|
||||
ImageClass, Interpolation, LocalVariable, Module, RelationalFunction, ScalarKind, ScalarValue,
|
||||
ShaderStage, Statement, StorageAccess, StorageClass, StorageFormat, StructMember, Type,
|
||||
TypeInner, UnaryOperator,
|
||||
ImageClass, Interpolation, LocalVariable, Module, RelationalFunction, Sampling, ScalarKind,
|
||||
ScalarValue, ShaderStage, Statement, StorageAccess, StorageClass, StorageFormat, StructMember,
|
||||
Type, TypeInner, UnaryOperator,
|
||||
|
||||
};
|
||||
use features::FeaturesManager;
|
||||
use std::{
|
||||
@ -232,8 +233,10 @@ impl IdGenerator {
|
||||
/// Helper wrapper used to get a name for a varying
|
||||
///
|
||||
/// Varying have different naming schemes depending on their binding:
|
||||
/// - 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 builtin bindings get the from [`glsl_built_in`](glsl_built_in).
|
||||
/// - 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> {
|
||||
binding: &'a Binding,
|
||||
stage: ShaderStage,
|
||||
@ -793,16 +796,22 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let (location, interpolation) = match binding {
|
||||
Some(&Binding::Location { location, interpolation }) => (location, interpolation),
|
||||
let (location, interpolation, sampling) = match binding {
|
||||
Some(&Binding::Location { location, interpolation, sampling }) => (location, interpolation, sampling),
|
||||
_ => return Ok(()),
|
||||
};
|
||||
|
||||
// Write the interpolation modifier if needed
|
||||
//
|
||||
// We ignore all interpolation modifiers that aren't used in input globals in fragment
|
||||
// shaders or output globals in vertex shaders
|
||||
// We ignore all interpolation and auxiliary modifiers that aren't used in fragment
|
||||
// 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 self.options.shader_stage == ShaderStage::Fragment {
|
||||
if emit_interpolation_and_auxiliary {
|
||||
write!(self.out, "{} ", glsl_interpolation(interp))?;
|
||||
}
|
||||
}
|
||||
@ -811,13 +820,24 @@ impl<'a, W: Write> Writer<'a, W> {
|
||||
if self.options.version.supports_explicit_locations() {
|
||||
write!(
|
||||
self.out,
|
||||
"layout(location = {}) {} ",
|
||||
location,
|
||||
if output { "out" } else { "in" }
|
||||
)?;
|
||||
} else {
|
||||
write!(self.out, "{} ", if output { "out" } else { "in" })?;
|
||||
"layout(location = {}) ",
|
||||
location)?;
|
||||
}
|
||||
|
||||
// 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_type` adds no leading or trailing spaces
|
||||
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
|
||||
// Leading space is important
|
||||
let vname = VaryingName {
|
||||
binding: &Binding::Location { location, interpolation: None },
|
||||
binding: &Binding::Location { location, interpolation: None, sampling: None },
|
||||
stage: self.entry_point.stage,
|
||||
output,
|
||||
};
|
||||
@ -2201,8 +2221,15 @@ fn glsl_interpolation(interpolation: Interpolation) -> &'static str {
|
||||
Interpolation::Perspective => "smooth",
|
||||
Interpolation::Linear => "noperspective",
|
||||
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};
|
||||
|
||||
match *binding {
|
||||
crate::Binding::Location { location, interpolation } => {
|
||||
crate::Binding::Location { location, interpolation, sampling } => {
|
||||
self.decorate(id, Decoration::Location, &[location]);
|
||||
let interp_decoration = match interpolation {
|
||||
Some(crate::Interpolation::Linear) => Some(Decoration::NoPerspective),
|
||||
Some(crate::Interpolation::Flat) => Some(Decoration::Flat),
|
||||
Some(crate::Interpolation::Centroid) => Some(Decoration::Centroid),
|
||||
Some(crate::Interpolation::Sample) => Some(Decoration::Sample),
|
||||
Some(crate::Interpolation::Perspective) | None => None,
|
||||
};
|
||||
if let Some(decoration) = interp_decoration {
|
||||
self.decorate(id, decoration, &[]);
|
||||
|
||||
match interpolation {
|
||||
// Perspective-correct interpolation is the default in SPIR-V.
|
||||
None | Some(crate::Interpolation::Perspective) => (),
|
||||
Some(crate::Interpolation::Flat) => {
|
||||
self.decorate(id, Decoration::Flat, &[]);
|
||||
}
|
||||
Some(crate::Interpolation::Linear) => {
|
||||
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) => {
|
||||
|
@ -2,7 +2,8 @@ use super::{super::Typifier, constants::ConstantSolver, error::ErrorKind};
|
||||
use crate::{
|
||||
proc::ResolveContext, Arena, BinaryOperator, Binding, Constant, Expression, FastHashMap,
|
||||
Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module,
|
||||
RelationalFunction, ResourceBinding, ShaderStage, Statement, StorageClass, Type, UnaryOperator,
|
||||
RelationalFunction, ResourceBinding, Sampling, ShaderStage, Statement, StorageClass, Type,
|
||||
UnaryOperator,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -226,6 +227,7 @@ pub enum TypeQualifier {
|
||||
ResourceBinding(ResourceBinding),
|
||||
Binding(Binding),
|
||||
Interpolation(Interpolation),
|
||||
Sampling(Sampling),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -66,8 +66,8 @@ impl<'a> Iterator for Lexer<'a> {
|
||||
"flat" => Token::Interpolation((meta, crate::Interpolation::Flat)),
|
||||
"noperspective" => Token::Interpolation((meta, crate::Interpolation::Linear)),
|
||||
"smooth" => Token::Interpolation((meta, crate::Interpolation::Perspective)),
|
||||
"centroid" => Token::Interpolation((meta, crate::Interpolation::Centroid)),
|
||||
"sample" => Token::Interpolation((meta, crate::Interpolation::Sample)),
|
||||
"centroid" => Token::Sampling((meta, crate::Sampling::Centroid)),
|
||||
"sample" => Token::Sampling((meta, crate::Sampling::Sample)),
|
||||
// values
|
||||
"true" => Token::BoolConstant((meta, true)),
|
||||
"false" => Token::BoolConstant((meta, false)),
|
||||
|
@ -10,7 +10,7 @@ pomelo! {
|
||||
ConstantInner, Expression,
|
||||
Function, FunctionArgument, FunctionResult,
|
||||
GlobalVariable, Handle, Interpolation,
|
||||
LocalVariable, ResourceBinding, ScalarValue, ScalarKind,
|
||||
LocalVariable, ResourceBinding, Sampling, ScalarValue, ScalarKind,
|
||||
Statement, StorageAccess, StorageClass, StructMember,
|
||||
SwitchCase, Type, TypeInner, UnaryOperator,
|
||||
};
|
||||
@ -120,6 +120,8 @@ pomelo! {
|
||||
%type storage_qualifier StorageQualifier;
|
||||
%type interpolation_qualifier Interpolation;
|
||||
%type Interpolation Interpolation;
|
||||
%type sampling_qualifier Sampling;
|
||||
%type Sampling Sampling;
|
||||
|
||||
// types
|
||||
%type fully_specified_type (Vec<TypeQualifier>, Option<Handle<Type>>);
|
||||
@ -613,10 +615,15 @@ pomelo! {
|
||||
i
|
||||
}
|
||||
|
||||
sampling_qualifier ::= Sampling((_, s)) {
|
||||
s
|
||||
}
|
||||
|
||||
layout_qualifier ::= Layout LeftParen layout_qualifier_id_list(l) RightParen {
|
||||
if let Some(&(_, location)) = l.iter().find(|&q| q.0.as_str() == "location") {
|
||||
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") {
|
||||
let group = if let Some(&(_, set)) = l.iter().find(|&q| q.0.as_str() == "set") {
|
||||
set
|
||||
@ -670,6 +677,9 @@ pomelo! {
|
||||
single_type_qualifier ::= interpolation_qualifier(i) {
|
||||
TypeQualifier::Interpolation(i)
|
||||
}
|
||||
single_type_qualifier ::= sampling_qualifier(i) {
|
||||
TypeQualifier::Sampling(i)
|
||||
}
|
||||
// single_type_qualifier ::= invariant_qualifier;
|
||||
// single_type_qualifier ::= precise_qualifier;
|
||||
|
||||
@ -1133,8 +1143,16 @@ pomelo! {
|
||||
let interpolation = d.type_qualifiers.iter().find_map(|tq| {
|
||||
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;
|
||||
*samp = sampling;
|
||||
}
|
||||
|
||||
for (id, _initializer) in d.ids_initializers {
|
||||
|
@ -220,6 +220,7 @@ struct Decoration {
|
||||
matrix_stride: Option<NonZeroU32>,
|
||||
matrix_major: Option<Majority>,
|
||||
interpolation: Option<crate::Interpolation>,
|
||||
sampling: Option<crate::Sampling>,
|
||||
flags: DecorationFlags,
|
||||
}
|
||||
|
||||
@ -253,8 +254,9 @@ impl Decoration {
|
||||
built_in: None,
|
||||
location: Some(location),
|
||||
interpolation,
|
||||
sampling,
|
||||
..
|
||||
} => Ok(crate::Binding::Location { location, interpolation }),
|
||||
} => Ok(crate::Binding::Location { location, interpolation, sampling }),
|
||||
_ => Err(Error::MissingDecoration(spirv::Decoration::Location)),
|
||||
}
|
||||
}
|
||||
@ -504,10 +506,10 @@ impl<I: Iterator<Item = u32>> Parser<I> {
|
||||
dec.interpolation = Some(crate::Interpolation::Flat);
|
||||
}
|
||||
spirv::Decoration::Centroid => {
|
||||
dec.interpolation = Some(crate::Interpolation::Centroid);
|
||||
dec.sampling = Some(crate::Sampling::Centroid);
|
||||
}
|
||||
spirv::Decoration::Sample => {
|
||||
dec.interpolation = Some(crate::Interpolation::Sample);
|
||||
dec.sampling = Some(crate::Sampling::Sample);
|
||||
}
|
||||
spirv::Decoration::NonReadable => {
|
||||
dec.flags |= DecorationFlags::NON_READABLE;
|
||||
|
@ -44,13 +44,19 @@ pub fn map_interpolation(word: &str) -> Result<crate::Interpolation, Error<'_>>
|
||||
match word {
|
||||
"linear" => Ok(crate::Interpolation::Linear),
|
||||
"flat" => Ok(crate::Interpolation::Flat),
|
||||
"centroid" => Ok(crate::Interpolation::Centroid),
|
||||
"sample" => Ok(crate::Interpolation::Sample),
|
||||
"perspective" => Ok(crate::Interpolation::Perspective),
|
||||
_ => 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<'_>> {
|
||||
use crate::StorageFormat as Sf;
|
||||
Ok(match word {
|
||||
|
@ -112,11 +112,12 @@ pub enum Error<'a> {
|
||||
ZeroSizeOrAlign,
|
||||
#[error("not a composite type: {0:?}")]
|
||||
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(
|
||||
Option<u32>,
|
||||
Option<crate::BuiltIn>,
|
||||
Option<crate::Interpolation>,
|
||||
Option<crate::Sampling>,
|
||||
),
|
||||
#[error("call to local `{0}(..)` can't be resolved")]
|
||||
UnknownLocalFunction(&'a str),
|
||||
@ -470,6 +471,7 @@ struct BindingParser {
|
||||
location: Option<u32>,
|
||||
built_in: Option<crate::BuiltIn>,
|
||||
interpolation: Option<crate::Interpolation>,
|
||||
sampling: Option<crate::Sampling>,
|
||||
}
|
||||
|
||||
impl BindingParser {
|
||||
@ -490,6 +492,10 @@ impl BindingParser {
|
||||
lexer.expect(Token::Paren('('))?;
|
||||
let raw = lexer.next_ident()?;
|
||||
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(')'))?;
|
||||
}
|
||||
_ => return Err(Error::UnknownAttribute(name)),
|
||||
@ -498,16 +504,17 @@ impl BindingParser {
|
||||
}
|
||||
|
||||
fn finish<'a>(self) -> Result<Option<crate::Binding>, Error<'a>> {
|
||||
match (self.location, self.built_in, self.interpolation) {
|
||||
(None, None, None) => Ok(None),
|
||||
(Some(location), None, interpolation) => {
|
||||
Ok(Some(crate::Binding::Location { location, interpolation }))
|
||||
match (self.location, self.built_in, self.interpolation, self.sampling) {
|
||||
(None, None, None, None) => Ok(None),
|
||||
(Some(location), None, interpolation, sampling) => {
|
||||
Ok(Some(crate::Binding::Location { location, interpolation, sampling }))
|
||||
}
|
||||
(None, Some(bi), None) => Ok(Some(crate::Binding::BuiltIn(bi))),
|
||||
(location, built_in, interpolation) => Err(Error::InconsistentBinding(
|
||||
(None, Some(bi), None, None) => Ok(Some(crate::Binding::BuiltIn(bi))),
|
||||
(location, built_in, interpolation, sampling) => Err(Error::InconsistentBinding(
|
||||
location,
|
||||
built_in,
|
||||
interpolation,
|
||||
sampling,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
26
src/lib.rs
26
src/lib.rs
@ -226,11 +226,23 @@ pub enum Interpolation {
|
||||
Linear,
|
||||
/// Indicates that no interpolation will be performed.
|
||||
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,
|
||||
/// 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,
|
||||
}
|
||||
|
||||
@ -465,7 +477,11 @@ pub enum Binding {
|
||||
/// Built-in shader variable.
|
||||
BuiltIn(BuiltIn),
|
||||
/// Indexed location.
|
||||
Location { location: u32, interpolation: Option<Interpolation> },
|
||||
Location {
|
||||
location: u32,
|
||||
interpolation: Option<Interpolation>,
|
||||
sampling: Option<Sampling>
|
||||
},
|
||||
}
|
||||
|
||||
/// Pipeline binding information for global resources.
|
||||
|
@ -206,7 +206,7 @@ impl VaryingContext<'_> {
|
||||
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) {
|
||||
return Err(VaryingError::BindingCollision { location });
|
||||
}
|
||||
@ -218,6 +218,11 @@ impl VaryingContext<'_> {
|
||||
if !needs_interpolation && interpolation.is_some() {
|
||||
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() {
|
||||
Some(crate::ScalarKind::Float) => {}
|
||||
Some(_)
|
||||
|
@ -1,10 +1,12 @@
|
||||
struct FragmentInput {
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
[[location(0), interpolate(flat)]] flat : u32;
|
||||
[[location(1), interpolate(linear)]] linear: f32;
|
||||
[[location(2), interpolate(centroid)]] centroid: vec2<f32>;
|
||||
[[location(3), interpolate(sample)]] sample: vec3<f32>;
|
||||
[[location(4), interpolate(perspective)]] perspective: vec4<f32>;
|
||||
[[location(1), interpolate(linear)]] linear : f32;
|
||||
[[location(2), interpolate(linear,centroid)]] linear_centroid : vec2<f32>;
|
||||
[[location(3), interpolate(linear,sample)]] linear_sample : vec3<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)]]
|
||||
@ -14,9 +16,11 @@ fn main() -> FragmentInput {
|
||||
out.position = vec4<f32>(2.0, 4.0, 5.0, 6.0);
|
||||
out.flat = 8u32;
|
||||
out.linear = 27.0;
|
||||
out.centroid = vec2<f32>(64.0, 125.0);
|
||||
out.sample = vec3<f32>(216.0, 343.0, 512.0);
|
||||
out.linear_centroid = vec2<f32>(64.0, 125.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_centroid = 2197.0;
|
||||
out.perspective_sample = 2744.0;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
@ -3,19 +3,23 @@ struct FragmentInput {
|
||||
vec4 position;
|
||||
uint flat1;
|
||||
float linear;
|
||||
vec2 centroid1;
|
||||
vec3 sample1;
|
||||
vec2 linear_centroid;
|
||||
vec3 linear_sample;
|
||||
vec4 perspective;
|
||||
float perspective_centroid;
|
||||
float perspective_sample;
|
||||
};
|
||||
|
||||
flat in uint _vs2fs_location0;
|
||||
noperspective in float _vs2fs_location1;
|
||||
centroid in vec2 _vs2fs_location2;
|
||||
sample in vec3 _vs2fs_location3;
|
||||
noperspective centroid in vec2 _vs2fs_location2;
|
||||
noperspective sample in vec3 _vs2fs_location3;
|
||||
smooth in vec4 _vs2fs_location4;
|
||||
smooth centroid in float _vs2fs_location5;
|
||||
smooth sample in float _vs2fs_location6;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -3,31 +3,39 @@ struct FragmentInput {
|
||||
vec4 position;
|
||||
uint flat1;
|
||||
float linear;
|
||||
vec2 centroid1;
|
||||
vec3 sample1;
|
||||
vec2 linear_centroid;
|
||||
vec3 linear_sample;
|
||||
vec4 perspective;
|
||||
float perspective_centroid;
|
||||
float perspective_sample;
|
||||
};
|
||||
|
||||
out uint _vs2fs_location0;
|
||||
out float _vs2fs_location1;
|
||||
out vec2 _vs2fs_location2;
|
||||
out vec3 _vs2fs_location3;
|
||||
out vec4 _vs2fs_location4;
|
||||
flat out uint _vs2fs_location0;
|
||||
noperspective out float _vs2fs_location1;
|
||||
noperspective centroid out vec2 _vs2fs_location2;
|
||||
noperspective sample out vec3 _vs2fs_location3;
|
||||
smooth out vec4 _vs2fs_location4;
|
||||
smooth centroid out float _vs2fs_location5;
|
||||
smooth sample out float _vs2fs_location6;
|
||||
|
||||
void main() {
|
||||
FragmentInput out1;
|
||||
out1.position = vec4(2.0, 4.0, 5.0, 6.0);
|
||||
out1.flat1 = 8u;
|
||||
out1.linear = 27.0;
|
||||
out1.centroid1 = vec2(64.0, 125.0);
|
||||
out1.sample1 = vec3(216.0, 343.0, 512.0);
|
||||
out1.linear_centroid = vec2(64.0, 125.0);
|
||||
out1.linear_sample = vec3(216.0, 343.0, 512.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;
|
||||
_vs2fs_location0 = out1.flat1;
|
||||
_vs2fs_location1 = out1.linear;
|
||||
_vs2fs_location2 = out1.centroid1;
|
||||
_vs2fs_location3 = out1.sample1;
|
||||
_vs2fs_location2 = out1.linear_centroid;
|
||||
_vs2fs_location3 = out1.linear_sample;
|
||||
_vs2fs_location4 = out1.perspective;
|
||||
_vs2fs_location5 = out1.perspective_centroid;
|
||||
_vs2fs_location6 = out1.perspective_sample;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -5,18 +5,22 @@ struct FragmentInput {
|
||||
metal::float4 position;
|
||||
metal::uint flat;
|
||||
float linear;
|
||||
metal::float2 centroid;
|
||||
metal::float3 sample;
|
||||
metal::float2 linear_centroid;
|
||||
metal::float3 linear_sample;
|
||||
metal::float4 perspective;
|
||||
float perspective_centroid;
|
||||
float perspective_sample;
|
||||
};
|
||||
|
||||
struct main1Output {
|
||||
metal::float4 position [[position]];
|
||||
metal::uint flat [[user(loc0)]];
|
||||
float linear [[user(loc1)]];
|
||||
metal::float2 centroid [[user(loc2)]];
|
||||
metal::float3 sample [[user(loc3)]];
|
||||
metal::float2 linear_centroid [[user(loc2)]];
|
||||
metal::float3 linear_sample [[user(loc3)]];
|
||||
metal::float4 perspective [[user(loc4)]];
|
||||
float perspective_centroid [[user(loc5)]];
|
||||
float perspective_sample [[user(loc6)]];
|
||||
};
|
||||
vertex main1Output main1(
|
||||
) {
|
||||
@ -24,25 +28,29 @@ vertex main1Output main1(
|
||||
out.position = metal::float4(2.0, 4.0, 5.0, 6.0);
|
||||
out.flat = 8u;
|
||||
out.linear = 27.0;
|
||||
out.centroid = metal::float2(64.0, 125.0);
|
||||
out.sample = metal::float3(216.0, 343.0, 512.0);
|
||||
out.linear_centroid = metal::float2(64.0, 125.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_centroid = 2197.0;
|
||||
out.perspective_sample = 2744.0;
|
||||
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 {
|
||||
metal::uint flat [[user(loc0)]];
|
||||
float linear [[user(loc1)]];
|
||||
metal::float2 centroid [[user(loc2)]];
|
||||
metal::float3 sample [[user(loc3)]];
|
||||
metal::float2 linear_centroid [[user(loc2)]];
|
||||
metal::float3 linear_sample [[user(loc3)]];
|
||||
metal::float4 perspective [[user(loc4)]];
|
||||
float perspective_centroid [[user(loc5)]];
|
||||
float perspective_sample [[user(loc6)]];
|
||||
};
|
||||
fragment void main2(
|
||||
main2Input varyings1 [[stage_in]]
|
||||
, 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;
|
||||
}
|
||||
|
@ -1,63 +1,83 @@
|
||||
; SPIR-V
|
||||
; Version: 1.0
|
||||
; Generator: rspirv
|
||||
; Bound: 95
|
||||
; Bound: 109
|
||||
OpCapability Shader
|
||||
OpCapability SampleRateShading
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Vertex %38 "main" %27 %29 %31 %33 %35 %37
|
||||
OpEntryPoint Fragment %93 "main" %76 %79 %82 %85 %88 %91
|
||||
OpExecutionMode %93 OriginUpperLeft
|
||||
OpEntryPoint Vertex %42 "main" %29 %31 %33 %35 %37 %39 %40 %41
|
||||
OpEntryPoint Fragment %107 "main" %86 %89 %92 %95 %98 %101 %103 %105
|
||||
OpExecutionMode %107 OriginUpperLeft
|
||||
OpSource GLSL 450
|
||||
OpName %23 "FragmentInput"
|
||||
OpMemberName %23 0 "position"
|
||||
OpMemberName %23 1 "flat"
|
||||
OpMemberName %23 2 "linear"
|
||||
OpMemberName %23 3 "centroid"
|
||||
OpMemberName %23 4 "sample"
|
||||
OpMemberName %23 5 "perspective"
|
||||
OpName %24 "out"
|
||||
OpName %27 "position"
|
||||
OpName %29 "flat"
|
||||
OpName %31 "linear"
|
||||
OpName %33 "centroid"
|
||||
OpName %35 "sample"
|
||||
OpName %37 "perspective"
|
||||
OpName %38 "main"
|
||||
OpName %76 "position"
|
||||
OpName %79 "flat"
|
||||
OpName %82 "linear"
|
||||
OpName %85 "centroid"
|
||||
OpName %88 "sample"
|
||||
OpName %91 "perspective"
|
||||
OpName %93 "main"
|
||||
OpMemberDecorate %23 0 Offset 0
|
||||
OpMemberDecorate %23 1 Offset 16
|
||||
OpMemberDecorate %23 2 Offset 20
|
||||
OpMemberDecorate %23 3 Offset 24
|
||||
OpMemberDecorate %23 4 Offset 32
|
||||
OpMemberDecorate %23 5 Offset 48
|
||||
OpDecorate %27 BuiltIn Position
|
||||
OpDecorate %29 Location 0
|
||||
OpDecorate %29 Flat
|
||||
OpDecorate %31 Location 1
|
||||
OpDecorate %31 NoPerspective
|
||||
OpDecorate %33 Location 2
|
||||
OpDecorate %33 Centroid
|
||||
OpDecorate %35 Location 3
|
||||
OpDecorate %35 Sample
|
||||
OpDecorate %37 Location 4
|
||||
OpDecorate %76 BuiltIn FragCoord
|
||||
OpDecorate %79 Location 0
|
||||
OpDecorate %79 Flat
|
||||
OpDecorate %82 Location 1
|
||||
OpDecorate %82 NoPerspective
|
||||
OpDecorate %85 Location 2
|
||||
OpDecorate %85 Centroid
|
||||
OpDecorate %88 Location 3
|
||||
OpDecorate %88 Sample
|
||||
OpDecorate %91 Location 4
|
||||
OpName %25 "FragmentInput"
|
||||
OpMemberName %25 0 "position"
|
||||
OpMemberName %25 1 "flat"
|
||||
OpMemberName %25 2 "linear"
|
||||
OpMemberName %25 3 "linear_centroid"
|
||||
OpMemberName %25 4 "linear_sample"
|
||||
OpMemberName %25 5 "perspective"
|
||||
OpMemberName %25 6 "perspective_centroid"
|
||||
OpMemberName %25 7 "perspective_sample"
|
||||
OpName %26 "out"
|
||||
OpName %29 "position"
|
||||
OpName %31 "flat"
|
||||
OpName %33 "linear"
|
||||
OpName %35 "linear_centroid"
|
||||
OpName %37 "linear_sample"
|
||||
OpName %39 "perspective"
|
||||
OpName %40 "perspective_centroid"
|
||||
OpName %41 "perspective_sample"
|
||||
OpName %42 "main"
|
||||
OpName %86 "position"
|
||||
OpName %89 "flat"
|
||||
OpName %92 "linear"
|
||||
OpName %95 "linear_centroid"
|
||||
OpName %98 "linear_sample"
|
||||
OpName %101 "perspective"
|
||||
OpName %103 "perspective_centroid"
|
||||
OpName %105 "perspective_sample"
|
||||
OpName %107 "main"
|
||||
OpMemberDecorate %25 0 Offset 0
|
||||
OpMemberDecorate %25 1 Offset 16
|
||||
OpMemberDecorate %25 2 Offset 20
|
||||
OpMemberDecorate %25 3 Offset 24
|
||||
OpMemberDecorate %25 4 Offset 32
|
||||
OpMemberDecorate %25 5 Offset 48
|
||||
OpMemberDecorate %25 6 Offset 64
|
||||
OpMemberDecorate %25 7 Offset 68
|
||||
OpDecorate %29 BuiltIn Position
|
||||
OpDecorate %31 Location 0
|
||||
OpDecorate %31 Flat
|
||||
OpDecorate %33 Location 1
|
||||
OpDecorate %33 NoPerspective
|
||||
OpDecorate %35 Location 2
|
||||
OpDecorate %35 NoPerspective
|
||||
OpDecorate %35 Centroid
|
||||
OpDecorate %37 Location 3
|
||||
OpDecorate %37 NoPerspective
|
||||
OpDecorate %37 Sample
|
||||
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
|
||||
%4 = OpTypeFloat 32
|
||||
%3 = OpConstant %4 2.0
|
||||
@ -76,97 +96,115 @@ OpDecorate %91 Location 4
|
||||
%17 = OpConstant %4 1000.0
|
||||
%18 = OpConstant %4 1331.0
|
||||
%19 = OpConstant %4 1728.0
|
||||
%20 = OpTypeVector %4 4
|
||||
%21 = OpTypeVector %4 2
|
||||
%22 = OpTypeVector %4 3
|
||||
%23 = OpTypeStruct %20 %9 %4 %21 %22 %20
|
||||
%25 = OpTypePointer Function %23
|
||||
%28 = OpTypePointer Output %20
|
||||
%27 = OpVariable %28 Output
|
||||
%30 = OpTypePointer Output %9
|
||||
%20 = OpConstant %4 2197.0
|
||||
%21 = OpConstant %4 2744.0
|
||||
%22 = OpTypeVector %4 4
|
||||
%23 = OpTypeVector %4 2
|
||||
%24 = OpTypeVector %4 3
|
||||
%25 = OpTypeStruct %22 %9 %4 %23 %24 %22 %4 %4
|
||||
%27 = OpTypePointer Function %25
|
||||
%30 = OpTypePointer Output %22
|
||||
%29 = OpVariable %30 Output
|
||||
%32 = OpTypePointer Output %4
|
||||
%32 = OpTypePointer Output %9
|
||||
%31 = OpVariable %32 Output
|
||||
%34 = OpTypePointer Output %21
|
||||
%34 = OpTypePointer Output %4
|
||||
%33 = OpVariable %34 Output
|
||||
%36 = OpTypePointer Output %22
|
||||
%36 = OpTypePointer Output %23
|
||||
%35 = OpVariable %36 Output
|
||||
%37 = OpVariable %28 Output
|
||||
%39 = OpTypeFunction %2
|
||||
%41 = OpTypePointer Function %20
|
||||
%43 = OpTypeInt 32 1
|
||||
%44 = OpConstant %43 0
|
||||
%46 = OpTypePointer Function %9
|
||||
%47 = OpConstant %43 1
|
||||
%49 = OpTypePointer Function %4
|
||||
%50 = OpConstant %43 2
|
||||
%52 = OpTypePointer Function %21
|
||||
%54 = OpConstant %43 3
|
||||
%56 = OpTypePointer Function %22
|
||||
%58 = OpConstant %43 4
|
||||
%61 = OpConstant %43 5
|
||||
%66 = OpTypePointer Output %4
|
||||
%77 = OpTypePointer Input %20
|
||||
%76 = OpVariable %77 Input
|
||||
%80 = OpTypePointer Input %9
|
||||
%79 = OpVariable %80 Input
|
||||
%83 = OpTypePointer Input %4
|
||||
%82 = OpVariable %83 Input
|
||||
%86 = OpTypePointer Input %21
|
||||
%85 = OpVariable %86 Input
|
||||
%89 = OpTypePointer Input %22
|
||||
%88 = OpVariable %89 Input
|
||||
%91 = OpVariable %77 Input
|
||||
%38 = OpFunction %2 None %39
|
||||
%26 = OpLabel
|
||||
%24 = OpVariable %25 Function
|
||||
OpBranch %40
|
||||
%40 = OpLabel
|
||||
%42 = OpCompositeConstruct %20 %3 %5 %6 %7
|
||||
%45 = OpAccessChain %41 %24 %44
|
||||
OpStore %45 %42
|
||||
%48 = OpAccessChain %46 %24 %47
|
||||
OpStore %48 %8
|
||||
%51 = OpAccessChain %49 %24 %50
|
||||
OpStore %51 %10
|
||||
%53 = OpCompositeConstruct %21 %11 %12
|
||||
%55 = OpAccessChain %52 %24 %54
|
||||
OpStore %55 %53
|
||||
%57 = OpCompositeConstruct %22 %13 %14 %15
|
||||
%59 = OpAccessChain %56 %24 %58
|
||||
%38 = OpTypePointer Output %24
|
||||
%37 = OpVariable %38 Output
|
||||
%39 = OpVariable %30 Output
|
||||
%40 = OpVariable %34 Output
|
||||
%41 = OpVariable %34 Output
|
||||
%43 = OpTypeFunction %2
|
||||
%45 = OpTypePointer Function %22
|
||||
%47 = OpTypeInt 32 1
|
||||
%48 = OpConstant %47 0
|
||||
%50 = OpTypePointer Function %9
|
||||
%51 = OpConstant %47 1
|
||||
%53 = OpTypePointer Function %4
|
||||
%54 = OpConstant %47 2
|
||||
%56 = OpTypePointer Function %23
|
||||
%58 = OpConstant %47 3
|
||||
%60 = OpTypePointer Function %24
|
||||
%62 = OpConstant %47 4
|
||||
%65 = OpConstant %47 5
|
||||
%67 = OpConstant %47 6
|
||||
%69 = OpConstant %47 7
|
||||
%74 = OpTypePointer Output %4
|
||||
%87 = OpTypePointer Input %22
|
||||
%86 = OpVariable %87 Input
|
||||
%90 = OpTypePointer Input %9
|
||||
%89 = OpVariable %90 Input
|
||||
%93 = OpTypePointer Input %4
|
||||
%92 = OpVariable %93 Input
|
||||
%96 = OpTypePointer Input %23
|
||||
%95 = OpVariable %96 Input
|
||||
%99 = OpTypePointer Input %24
|
||||
%98 = OpVariable %99 Input
|
||||
%101 = OpVariable %87 Input
|
||||
%103 = OpVariable %93 Input
|
||||
%105 = OpVariable %93 Input
|
||||
%42 = OpFunction %2 None %43
|
||||
%28 = OpLabel
|
||||
%26 = OpVariable %27 Function
|
||||
OpBranch %44
|
||||
%44 = OpLabel
|
||||
%46 = OpCompositeConstruct %22 %3 %5 %6 %7
|
||||
%49 = OpAccessChain %45 %26 %48
|
||||
OpStore %49 %46
|
||||
%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
|
||||
%60 = OpCompositeConstruct %20 %16 %17 %18 %19
|
||||
%62 = OpAccessChain %41 %24 %61
|
||||
OpStore %62 %60
|
||||
%63 = OpLoad %23 %24
|
||||
%64 = OpCompositeExtract %20 %63 0
|
||||
OpStore %27 %64
|
||||
%65 = OpAccessChain %66 %27 %47
|
||||
%67 = OpLoad %4 %65
|
||||
%68 = OpFNegate %4 %67
|
||||
OpStore %65 %68
|
||||
%69 = OpCompositeExtract %9 %63 1
|
||||
OpStore %29 %69
|
||||
%70 = OpCompositeExtract %4 %63 2
|
||||
OpStore %31 %70
|
||||
%71 = OpCompositeExtract %21 %63 3
|
||||
OpStore %33 %71
|
||||
%72 = OpCompositeExtract %22 %63 4
|
||||
OpStore %35 %72
|
||||
%73 = OpCompositeExtract %20 %63 5
|
||||
OpStore %37 %73
|
||||
%61 = OpCompositeConstruct %24 %13 %14 %15
|
||||
%63 = OpAccessChain %60 %26 %62
|
||||
OpStore %63 %61
|
||||
%64 = OpCompositeConstruct %22 %16 %17 %18 %19
|
||||
%66 = OpAccessChain %45 %26 %65
|
||||
OpStore %66 %64
|
||||
%68 = OpAccessChain %53 %26 %67
|
||||
OpStore %68 %20
|
||||
%70 = OpAccessChain %53 %26 %69
|
||||
OpStore %70 %21
|
||||
%71 = OpLoad %25 %26
|
||||
%72 = OpCompositeExtract %22 %71 0
|
||||
OpStore %29 %72
|
||||
%73 = OpAccessChain %74 %29 %51
|
||||
%75 = OpLoad %4 %73
|
||||
%76 = OpFNegate %4 %75
|
||||
OpStore %73 %76
|
||||
%77 = OpCompositeExtract %9 %71 1
|
||||
OpStore %31 %77
|
||||
%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
|
||||
OpFunctionEnd
|
||||
%93 = OpFunction %2 None %39
|
||||
%74 = OpLabel
|
||||
%78 = OpLoad %20 %76
|
||||
%81 = OpLoad %9 %79
|
||||
%84 = OpLoad %4 %82
|
||||
%87 = OpLoad %21 %85
|
||||
%90 = OpLoad %22 %88
|
||||
%92 = OpLoad %20 %91
|
||||
%75 = OpCompositeConstruct %23 %78 %81 %84 %87 %90 %92
|
||||
OpBranch %94
|
||||
%94 = OpLabel
|
||||
%107 = OpFunction %2 None %43
|
||||
%84 = OpLabel
|
||||
%88 = OpLoad %22 %86
|
||||
%91 = OpLoad %9 %89
|
||||
%94 = OpLoad %4 %92
|
||||
%97 = OpLoad %23 %95
|
||||
%100 = OpLoad %24 %98
|
||||
%102 = OpLoad %22 %101
|
||||
%104 = OpLoad %4 %103
|
||||
%106 = OpLoad %4 %105
|
||||
%85 = OpCompositeConstruct %25 %88 %91 %94 %97 %100 %102 %104 %106
|
||||
OpBranch %108
|
||||
%108 = OpLabel
|
||||
OpReturn
|
||||
OpFunctionEnd
|
@ -1520,6 +1520,7 @@
|
||||
binding: Some(Location(
|
||||
location: 0,
|
||||
interpolation: Some(Perspective),
|
||||
sampling: None,
|
||||
)),
|
||||
),
|
||||
(
|
||||
@ -1528,6 +1529,7 @@
|
||||
binding: Some(Location(
|
||||
location: 1,
|
||||
interpolation: Some(Perspective),
|
||||
sampling: None,
|
||||
)),
|
||||
),
|
||||
],
|
||||
@ -1536,6 +1538,7 @@
|
||||
binding: Some(Location(
|
||||
location: 0,
|
||||
interpolation: None,
|
||||
sampling: None,
|
||||
)),
|
||||
)),
|
||||
local_variables: [],
|
||||
|
Loading…
Reference in New Issue
Block a user