From 6cfd34ed5f6d175455d3b8988d7425f5950e79c3 Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Mon, 4 Sep 2023 21:38:44 -0400 Subject: [PATCH] wgpu-core: Only produce StageError::InputNotConsumed on DX11/DX12 This error only exists due to an issue with naga's HLSL support: https://github.com/gfx-rs/naga/issues/1945 The WGPU spec itself allows vertex shader outputs that are not consumed by the fragment shader. Until the issue is fixed, we can allow unconsumed outputs on all platforms other than DX11/DX12. --- CHANGELOG.md | 1 + wgpu-core/src/device/resource.rs | 2 +- wgpu-core/src/validation.rs | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ca6f6350a2..8e7e732cf2d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -93,6 +93,7 @@ By @Valaphee in [#3402](https://github.com/gfx-rs/wgpu/pull/3402) - Derive storage bindings via `naga::StorageAccess` instead of `naga::GlobalUse`. By @teoxoy in [#3985](https://github.com/gfx-rs/wgpu/pull/3985). - `Queue::on_submitted_work_done` callbacks will now always be called after all previous `BufferSlice::map_async` callbacks, even when there are no active submissions. By @cwfitzgerald in [#4036](https://github.com/gfx-rs/wgpu/pull/4036). - Fix `clear` texture views being leaked when `wgpu::SurfaceTexture` is dropped before it is presented. By @rajveermalviya in [#4057](https://github.com/gfx-rs/wgpu/pull/4057). +- Only produce `StageError::InputNotConsumed` on DX11/DX12. By @Aaron1011 in [#4116](https://github.com/gfx-rs/wgpu/pull/4116). #### Vulkan - Fix enabling `wgpu::Features::PARTIALLY_BOUND_BINDING_ARRAY` not being actually enabled in vulkan backend. By @39ali in[#3772](https://github.com/gfx-rs/wgpu/pull/3772). diff --git a/wgpu-core/src/device/resource.rs b/wgpu-core/src/device/resource.rs index 73f1887e10d..69753272e87 100644 --- a/wgpu-core/src/device/resource.rs +++ b/wgpu-core/src/device/resource.rs @@ -1286,7 +1286,7 @@ impl Device { inner: Box::new(inner), }) })?; - let interface = validation::Interface::new(&module, &info, self.limits.clone()); + let interface = validation::Interface::new(&module, &info, self.limits.clone(), A::VARIANT); let hal_shader = hal::ShaderInput::Naga(hal::NagaShader { module, info }); let hal_desc = hal::ShaderModuleDescriptor { diff --git a/wgpu-core/src/validation.rs b/wgpu-core/src/validation.rs index 84e1e71691d..5d96133cdac 100644 --- a/wgpu-core/src/validation.rs +++ b/wgpu-core/src/validation.rs @@ -121,6 +121,7 @@ struct EntryPoint { #[derive(Debug)] pub struct Interface { limits: wgt::Limits, + backend: wgt::Backend, resources: naga::Arena, entry_points: FastHashMap<(naga::ShaderStage, String), EntryPoint>, } @@ -829,7 +830,12 @@ impl Interface { list.push(varying); } - pub fn new(module: &naga::Module, info: &naga::valid::ModuleInfo, limits: wgt::Limits) -> Self { + pub fn new( + module: &naga::Module, + info: &naga::valid::ModuleInfo, + limits: wgt::Limits, + backend: wgt::Backend, + ) -> Self { let mut resources = naga::Arena::new(); let mut resource_mapping = FastHashMap::default(); for (var_handle, var) in module.global_variables.iter() { @@ -910,6 +916,7 @@ impl Interface { Self { limits, + backend, resources, entry_points, } @@ -1119,7 +1126,11 @@ impl Interface { } // Check all vertex outputs and make sure the fragment shader consumes them. - if shader_stage == naga::ShaderStage::Fragment { + // This is only needed for HLSL shaders (DX11 and DX12) due to a naga HLSL issue: + // https://github.com/gfx-rs/naga/issues/1945 + if shader_stage == naga::ShaderStage::Fragment + && matches!(self.backend, wgt::Backend::Dx11 | wgt::Backend::Dx12) + { for &index in inputs.keys() { // This is a linear scan, but the count should be low enough // that this should be fine.