#[non_exhaustive]pub enum ShaderPanicStrategy {
SilentExit,
DebugPrintfThenExit {
print_inputs: bool,
print_backtrace: bool,
},
UNSOUND_DO_NOT_USE_UndefinedBehaviorViaUnreachable,
}Expand description
Strategy used to handle Rust panic!s in shaders compiled to SPIR-V.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
SilentExit
Return from shader entry-point with no side-effects (default).
While similar to the standard SPIR-V OpTerminateInvocation, this is
not limited to fragment shaders, and instead supports all shaders
(as it’s handled via control-flow rewriting, instead of SPIR-V features).
DebugPrintfThenExit
Like SilentExit, but also using debugPrintf to report the panic in
a way that can reach the user, before returning from the entry-point.
Quick setup for enabling debugPrintf output (to stdout) at runtime:
- set these environment variables:
VK_LOADER_LAYERS_ENABLE=VK_LAYER_KHRONOS_validationVK_LAYER_PRINTF_ONLY_PRESET=1VK_LAYER_PRINTF_TO_STDOUT=1(not always needed, but can help)
- if using
wgpu, enablewgpu::Features::SPIRV_SHADER_PASSTHROUGH, and usecreate_shader_module_passthroughinstead ofcreate_shader_module - in case of errors, or no output (from a
panic!()/debug_printf!()), keep reading below for additional information and alternatives
Note: enabling this automatically adds the SPV_KHR_non_semantic_info
extension, as debugPrintf is from a “non-semantic extended instruction set”.
Note: debugPrintf output reaching the user involves:
- being able to load the shader in the first place:
- for
wgpu, use “SPIR-V shader passthrough” (Naga lacksdebugPrintf):- enable
wgpu::Features::SPIRV_SHADER_PASSTHROUGH - replace
create_shader_modulecalls withcreate_shader_module_passthrough
- enable
- in theory, the
VK_KHR_shader_non_semantic_infoVulkan Device extension (or requiring at least Vulkan 1.3, which incorporated it)- however, Validation Layers don’t actually check this anymore, since Vulkan SDK version 1.4.313.0 (and drivers shouldn’t care either)
- for
- general configurability of Vulkan SDK
and/or Vulkan Loader
- (this list doubles as a legend for shorthands used later below)
- env: setting environment variables on the fly
- easiest for quick testing, no code changes/rebuilding needed
- e.g.
FOO=1 cargo run ...(in UNIX-style shells)
- instance: programmatic control via
vkCreateInstance()params- best for integration with app-specific debugging functionality
- limited to direct Vulkan usage (e.g.
ash, notwgpu) VK_EXT_layer_settingsas aVK_LAYER_*environment variables analogue, e.g.VK_LAYER_FOOcontrolled by aVkLayerSettingEXTwith"foo"aspSettingName(and an appropriatetype/value), included inVkLayerSettingsCreateInfoEXT’spSettings
- on-disk configuration and interactive tooling, e.g.:
vk_layer_settings.txtfiles, either hand-written, or generated by the “Vulkan Configurator” GUI tool (included with the Vulkan SDK)- third-party Vulkan debuggers like
RenderDoc
- Vulkan Validation Layers
- (they contain the
debugPrintfimplementation, a SPIR-V -> SPIR-V translation) - enabled by one of (as per “general configurability” above):
- env:
VK_LOADER_LAYERS_ENABLE=VK_LAYER_KHRONOS_validation - instance:
"VK_LAYER_KHRONOS_validation"in the list of layers - via
wgpu:wgpu::InstanceFlags::VALIDATION
- env:
- (they contain the
- Validation Layers’
debugPrintfsupport (official docs):- enabled by one of (as per “general configurability” above):
- env:
VK_LAYER_PRINTF_ENABLE=1(validation +debugPrintf) - env:
VK_LAYER_PRINTF_ONLY_PRESET=1(onlydebugPrintf, no validation) - instance:
"printf_enable"/"printf_only_preset"viaVkLayerSettingEXT(i.e. analogues for the two environment variables) - instance:
VkValidationFeaturesEXTwithpEnabledValidationFeaturescontainingVK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT
- env:
- enabled by one of (as per “general configurability” above):
- outputting the
debugPrintfmessages sent back from the GPU:- defaults to common validation logging (itself defaulting to stdout)
- env:
VK_LAYER_PRINTF_TO_STDOUT=1(and its instance analogue) forces direct printing to stdout, bypassingVK_EXT_debug_utilsetc. - validation logging can itself be controlled via
VK_EXT_debug_utils wgpubuilt in debug mode (and/or with debug-assertions enabled):- it uses
VK_EXT_debug_utilsinternally, exposing it vialog - with e.g.
env_logger,RUST_LOG=infosuffices fordebugPrintfmessages (as they specifically have the “info” level) - other
log/tracingsubscribers should be configured similarly
- it uses
Fields
print_inputs: boolWhether to also print the entry-point inputs (excluding buffers/resources), which should uniquely identify the panicking shader invocation.
print_backtrace: boolWhether to also print a “backtrace” (i.e. the chain of function calls
that led to the panic!).
As there is no way to dynamically compute this information, the string
containing the full backtrace of each panic! is statically generated,
meaning this option could significantly increase binary size.
UNSOUND_DO_NOT_USE_UndefinedBehaviorViaUnreachable
Warning: this is unsound (i.e. adds Undefined Behavior to safe Rust code)
This option only exists for testing (hence the unfriendly name it has),
and more specifically testing whether conditional panics are responsible
for performance differences when upgrading from older Rust-GPU versions
(which used infinite loops for panics, that spirv-opt/drivers could’ve
sometimes treated as UB, and optimized as if they were impossible to reach).
Unlike those infinite loops, however, this uses OpUnreachable, so it
forces the old worst-case (all panic!s become UB and are optimized out).
Trait Implementations§
Source§impl Clone for ShaderPanicStrategy
impl Clone for ShaderPanicStrategy
Source§fn clone(&self) -> ShaderPanicStrategy
fn clone(&self) -> ShaderPanicStrategy
1.0.0 · Source§const fn clone_from(&mut self, source: &Self)
const fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ShaderPanicStrategy
impl Debug for ShaderPanicStrategy
Source§impl Default for ShaderPanicStrategy
impl Default for ShaderPanicStrategy
Source§fn default() -> ShaderPanicStrategy
fn default() -> ShaderPanicStrategy
Source§impl<'de> Deserialize<'de> for ShaderPanicStrategy
impl<'de> Deserialize<'de> for ShaderPanicStrategy
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for ShaderPanicStrategy
impl PartialEq for ShaderPanicStrategy
Source§impl Serialize for ShaderPanicStrategy
impl Serialize for ShaderPanicStrategy
impl Copy for ShaderPanicStrategy
impl Eq for ShaderPanicStrategy
impl StructuralPartialEq for ShaderPanicStrategy
Auto Trait Implementations§
impl Freeze for ShaderPanicStrategy
impl RefUnwindSafe for ShaderPanicStrategy
impl Send for ShaderPanicStrategy
impl Sync for ShaderPanicStrategy
impl Unpin for ShaderPanicStrategy
impl UnwindSafe for ShaderPanicStrategy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.