From 12d9ef2eca4bbd434294d116c7ad53731b930326 Mon Sep 17 00:00:00 2001 From: Connor Fitzgerald Date: Sun, 29 May 2022 18:07:00 -0400 Subject: [PATCH] Check that all vertex outputs are consumed by the fragment shader --- wgpu-core/src/validation.rs | 17 +++++++++++++++++ wgpu/examples/cube/shader.wgsl | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 148eeecfa5..a9d9856258 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -263,6 +263,8 @@ pub enum StageError { #[source] error: InputError, }, + #[error("location[{location}] is provided by the previous stage output but is not consumed as input by this stage.")] + InputNotConsumed { location: wgt::ShaderLocation }, } fn map_storage_format_to_naga(format: wgt::TextureFormat) -> Option { @@ -1158,6 +1160,21 @@ impl Interface { } } + // Check all vertex outputs and make sure the fragment shader consumes them. + if shader_stage == naga::ShaderStage::Fragment { + for &index in inputs.keys() { + // This is a linear scan, but the count should be low enough that this should be fine. + let found = entry_point.inputs.iter().any(|v| match *v { + Varying::Local { location, .. } => location == index, + Varying::BuiltIn(_) => false, + }); + + if !found { + return Err(StageError::InputNotConsumed { location: index }); + } + } + } + if shader_stage == naga::ShaderStage::Vertex { for output in entry_point.outputs.iter() { //TODO: count builtins towards the limit? diff --git a/wgpu/examples/cube/shader.wgsl b/wgpu/examples/cube/shader.wgsl index e79bd02610..8e9fa6c495 100644 --- a/wgpu/examples/cube/shader.wgsl +++ b/wgpu/examples/cube/shader.wgsl @@ -30,6 +30,6 @@ fn fs_main(vertex: VertexOutput) -> @location(0) vec4 { } @fragment -fn fs_wire() -> @location(0) vec4 { +fn fs_wire(vertex: VertexOutput) -> @location(0) vec4 { return vec4(0.0, 0.5, 0.0, 0.5); }