From fb305b85f692f3fbbd9509b648dfbc97072f7465 Mon Sep 17 00:00:00 2001 From: Erich Gubler Date: Thu, 28 Mar 2024 17:00:04 -0400 Subject: [PATCH] docs: add warning about stack size for WGSL compilation --- CHANGELOG.md | 2 +- naga/src/front/wgsl/mod.rs | 11 +++++++++++ wgpu-core/src/device/global.rs | 14 ++++++++++++++ wgpu/src/lib.rs | 13 +++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f629a2837..c80fcc8c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -155,7 +155,7 @@ Bottom level categories: - In spv-in, remove unnecessary "gl_PerVertex" name check so unused builtins will always be skipped. By @Imberflur in [#5227](https://github.com/gfx-rs/wgpu/pull/5227). - GLSL 410 does not support layout(binding = ...), enable only for GLSL 420. By @bes in [#5357](https://github.com/gfx-rs/wgpu/pull/5357) - In spv-out, check for acceleration and ray-query types when enabling ray-query extension to prevent validation error. By @Vecvec in [#5463](https://github.com/gfx-rs/wgpu/pull/5463) -- Add a limit for curly brace nesting in WGSL parsing. By @ErichDonGubler in [#5447](https://github.com/gfx-rs/wgpu/pull/5447). +- Add a limit for curly brace nesting in WGSL parsing, plus a note about stack size requirements. By @ErichDonGubler in [#5447](https://github.com/gfx-rs/wgpu/pull/5447). #### Tests diff --git a/naga/src/front/wgsl/mod.rs b/naga/src/front/wgsl/mod.rs index b6151fe1c..aec1e657f 100644 --- a/naga/src/front/wgsl/mod.rs +++ b/naga/src/front/wgsl/mod.rs @@ -44,6 +44,17 @@ impl Frontend { } } +///
+// NOTE: Keep this in sync with `wgpu::Device::create_shader_module`! +// NOTE: Keep this in sync with `wgpu_core::Global::device_create_shader_module`! +/// +/// This function may consume a lot of stack space. Compiler-enforced limits for parsing recursion +/// exist; if shader compilation runs into them, it will return an error gracefully. However, on +/// some build profiles and platforms, the default stack size for a thread may be exceeded before +/// this limit is reached during parsing. Callers should ensure that there is enough stack space +/// for this, particularly if calls to this method are exposed to user input. +/// +///
pub fn parse_str(source: &str) -> Result { Frontend::new().parse(source) } diff --git a/wgpu-core/src/device/global.rs b/wgpu-core/src/device/global.rs index 0c97e1b50..891a62ad2 100644 --- a/wgpu-core/src/device/global.rs +++ b/wgpu-core/src/device/global.rs @@ -1170,6 +1170,20 @@ impl Global { } } + /// Create a shader module with the given `source`. + /// + ///
+ // NOTE: Keep this in sync with `naga::front::wgsl::parse_str`! + // NOTE: Keep this in sync with `wgpu::Device::create_shader_module`! + /// + /// This function may consume a lot of stack space. Compiler-enforced limits for parsing + /// recursion exist; if shader compilation runs into them, it will return an error gracefully. + /// However, on some build profiles and platforms, the default stack size for a thread may be + /// exceeded before this limit is reached during parsing. Callers should ensure that there is + /// enough stack space for this, particularly if calls to this method are exposed to user + /// input. + /// + ///
pub fn device_create_shader_module( &self, device_id: DeviceId, diff --git a/wgpu/src/lib.rs b/wgpu/src/lib.rs index ecf5f88d8..a49c72a1e 100644 --- a/wgpu/src/lib.rs +++ b/wgpu/src/lib.rs @@ -2296,6 +2296,19 @@ impl Device { } /// Creates a shader module from either SPIR-V or WGSL source code. + /// + ///
+ // NOTE: Keep this in sync with `naga::front::wgsl::parse_str`! + // NOTE: Keep this in sync with `wgpu_core::Global::device_create_shader_module`! + /// + /// This function may consume a lot of stack space. Compiler-enforced limits for parsing + /// recursion exist; if shader compilation runs into them, it will return an error gracefully. + /// However, on some build profiles and platforms, the default stack size for a thread may be + /// exceeded before this limit is reached during parsing. Callers should ensure that there is + /// enough stack space for this, particularly if calls to this method are exposed to user + /// input. + /// + ///
pub fn create_shader_module(&self, desc: ShaderModuleDescriptor<'_>) -> ShaderModule { let (id, data) = DynContext::device_create_shader_module( &*self.context,