-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add per-vertex stuff #8591
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: trunk
Are you sure you want to change the base?
Add per-vertex stuff #8591
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,6 +78,7 @@ impl Iterator for Lexer<'_> { | |
| "invariant" => TokenValue::Invariant, | ||
| "flat" => TokenValue::Interpolation(crate::Interpolation::Flat), | ||
| "noperspective" => TokenValue::Interpolation(crate::Interpolation::Linear), | ||
| "pervertexEXT" => TokenValue::Interpolation(crate::Interpolation::PerVertex), | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure that we need to be parsing this for GLSL. If its super simple then why not, but otherwise I'll probably ignore or remove it. |
||
| "smooth" => TokenValue::Interpolation(crate::Interpolation::Perspective), | ||
| "centroid" => TokenValue::Sampling(crate::Sampling::Centroid), | ||
| "sample" => TokenValue::Sampling(crate::Sampling::Sample), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -98,6 +98,10 @@ pub enum VaryingError { | |
| InvalidPerPrimitive, | ||
| #[error("Non-builtin members of a mesh primitive output struct must be decorated with `@per_primitive`")] | ||
| MissingPerPrimitive, | ||
| #[error("The `PER_VERTEX` capability must be enabled to use per-vertex fragment inputs.")] | ||
| PerVertexNotAllowed, | ||
|
Comment on lines
+101
to
+102
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably just be a MissingCapability error |
||
| #[error("Per vertex fragment inputs must be an array of length 3.")] | ||
| PerVertexNotArrayOfThree, | ||
| } | ||
|
|
||
| #[derive(Clone, Debug, thiserror::Error)] | ||
|
|
@@ -441,8 +445,16 @@ impl VaryingContext<'_> { | |
| Capabilities::MESH_SHADER, | ||
| )); | ||
| } | ||
| if interpolation == Some(crate::Interpolation::PerVertex) { | ||
| if !self.capabilities.contains(Capabilities::SHADER_PER_VERTEX) | ||
| || self.stage != crate::ShaderStage::Fragment | ||
| { | ||
| return Err(VaryingError::PerVertexNotAllowed); | ||
| } | ||
| } | ||
| // Only IO-shareable types may be stored in locations. | ||
| if !self.type_info[ty.index()] | ||
| // Per Vertex case is checked later. | ||
| else if !self.type_info[ty.index()] | ||
| .flags | ||
| .contains(super::TypeFlags::IO_SHAREABLE) | ||
| { | ||
|
|
@@ -548,19 +560,32 @@ impl VaryingContext<'_> { | |
| return Err(VaryingError::UnsupportedCapability(required)); | ||
| } | ||
|
|
||
| match ty_inner.scalar_kind() { | ||
| Some(crate::ScalarKind::Float) => { | ||
| if needs_interpolation && interpolation.is_none() { | ||
| return Err(VaryingError::MissingInterpolation); | ||
| if interpolation == Some(crate::Interpolation::PerVertex) { | ||
| let three = crate::ArraySize::Constant(core::num::NonZeroU32::new(3).unwrap()); | ||
| match ty_inner { | ||
| &Ti::Array { base, size, .. } if size == three => { | ||
| if self.types[base].inner.scalar_kind().is_none() { | ||
| return Err(VaryingError::InvalidType(base)); | ||
| } | ||
| } | ||
| _ => return Err(VaryingError::PerVertexNotArrayOfThree), | ||
| } | ||
| Some(_) => { | ||
| if needs_interpolation && interpolation != Some(crate::Interpolation::Flat) | ||
| { | ||
| return Err(VaryingError::InvalidInterpolation); | ||
| } else { | ||
| match ty_inner.scalar_kind() { | ||
| Some(crate::ScalarKind::Float) => { | ||
| if needs_interpolation && interpolation.is_none() { | ||
| return Err(VaryingError::MissingInterpolation); | ||
| } | ||
| } | ||
| Some(_) => { | ||
| if needs_interpolation | ||
| && interpolation != Some(crate::Interpolation::Flat) | ||
| { | ||
| return Err(VaryingError::InvalidInterpolation); | ||
| } | ||
| } | ||
| None => return Err(VaryingError::InvalidType(ty)), | ||
| } | ||
| None => return Err(VaryingError::InvalidType(ty)), | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -83,7 +83,7 @@ bitflags::bitflags! { | |
| #[cfg_attr(feature = "serialize", derive(serde::Serialize))] | ||
| #[cfg_attr(feature = "deserialize", derive(serde::Deserialize))] | ||
| #[derive(Clone, Copy, Debug, Eq, PartialEq)] | ||
| pub struct Capabilities: u32 { | ||
| pub struct Capabilities: u64 { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've been waiting for the day! |
||
| /// Support for [`AddressSpace::PushConstant`][1]. | ||
| /// | ||
| /// [1]: crate::AddressSpace::PushConstant | ||
|
|
@@ -192,6 +192,8 @@ bitflags::bitflags! { | |
| const MESH_SHADER = 1 << 30; | ||
| /// Support for mesh shaders which output points. | ||
| const MESH_SHADER_POINT_TOPOLOGY = 1 << 31; | ||
| /// Support for per-vertex fragment input. | ||
| const SHADER_PER_VERTEX = 1 << 32; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| god_mode = true | ||
|
|
||
| [msl] | ||
| lang_version = [4, 0] | ||
|
|
||
| [hlsl] | ||
| shader_model = "V6_1" | ||
|
|
||
| [glsl] | ||
| version.Desktop = 450 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| @fragment | ||
| fn fs_main(@location(0) @interpolate(per_vertex) v: array<f32, 3>) -> @location(0) vec4<f32> { | ||
| return vec4(v[0], v[1], v[2], 1.0); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #version 450 core | ||
| #extension GL_EXT_fragment_shader_barycentric : require | ||
| layout(location = 0) pervertexEXT in float _vs2fs_location0; | ||
| layout(location = 0) out vec4 _fs2p_location0; | ||
|
|
||
| void main() { | ||
| float v = _vs2fs_location0; | ||
| _fs2p_location0 = vec4(v[0], v[1], v[2], 1.0); | ||
| return; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| struct FragmentInput_fs_main { | ||
| nointerpolation float v_1 : LOC0; | ||
| }; | ||
|
|
||
| float4 fs_main(FragmentInput_fs_main fragmentinput_fs_main) : SV_Target0 | ||
| { | ||
| float v[3] = fragmentinput_fs_main.v_1; | ||
| return float4(v[0], v[1], v[2], 1.0); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| ( | ||
| vertex:[ | ||
| ], | ||
| fragment:[ | ||
| ( | ||
| entry_point:"fs_main", | ||
| target_profile:"ps_6_1", | ||
| ), | ||
| ], | ||
| compute:[ | ||
| ], | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| // language: metal4.0 | ||
| #include <metal_stdlib> | ||
| #include <simd/simd.h> | ||
|
|
||
| using metal::uint; | ||
|
|
||
| struct type_1 { | ||
| float inner[3]; | ||
| }; | ||
|
|
||
| struct fs_mainInput { | ||
| type_1 v [[user(loc0), flat]]; | ||
| }; | ||
| struct fs_mainOutput { | ||
| metal::float4 member [[color(0)]]; | ||
| }; | ||
| fragment fs_mainOutput fs_main( | ||
| fs_mainInput varyings [[stage_in]] | ||
| ) { | ||
| const auto v = varyings.v; | ||
| return fs_mainOutput { metal::float4(v.inner[0], v.inner[1], v.inner[2], 1.0) }; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| ; SPIR-V | ||
| ; Version: 1.1 | ||
| ; Generator: rspirv | ||
| ; Bound: 22 | ||
| OpCapability Shader | ||
| OpCapability FragmentBarycentricKHR | ||
| OpExtension "SPV_KHR_fragment_shader_barycentric" | ||
| %1 = OpExtInstImport "GLSL.std.450" | ||
| OpMemoryModel Logical GLSL450 | ||
| OpEntryPoint Fragment %14 "fs_main" %9 %12 | ||
| OpExecutionMode %14 OriginUpperLeft | ||
| OpDecorate %4 ArrayStride 4 | ||
| OpDecorate %9 Location 0 | ||
| OpDecorate %9 PerVertexKHR | ||
| OpDecorate %12 Location 0 | ||
| %2 = OpTypeVoid | ||
| %3 = OpTypeFloat 32 | ||
| %6 = OpTypeInt 32 0 | ||
| %5 = OpConstant %6 3 | ||
| %4 = OpTypeArray %3 %5 | ||
| %7 = OpTypeVector %3 4 | ||
| %10 = OpTypePointer Input %4 | ||
| %9 = OpVariable %10 Input | ||
| %13 = OpTypePointer Output %7 | ||
| %12 = OpVariable %13 Output | ||
| %15 = OpTypeFunction %2 | ||
| %16 = OpConstant %3 1 | ||
| %14 = OpFunction %2 None %15 | ||
| %8 = OpLabel | ||
| %11 = OpLoad %4 %9 | ||
| OpBranch %17 | ||
| %17 = OpLabel | ||
| %18 = OpCompositeExtract %3 %11 0 | ||
| %19 = OpCompositeExtract %3 %11 1 | ||
| %20 = OpCompositeExtract %3 %11 2 | ||
| %21 = OpCompositeConstruct %7 %18 %19 %20 %16 | ||
| OpStore %12 %21 | ||
| OpReturn | ||
| OpFunctionEnd |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| @fragment | ||
| fn fs_main(@location(0) @interpolate(per_vertex) v: array<f32, 3>) -> @location(0) vec4<f32> { | ||
| return vec4<f32>(v[0], v[1], v[2], 1f); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we need to be worrying about GLSL output, especially if this is only for Vulkan accepted GLSL