#[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_validation
VK_LAYER_PRINTF_ONLY_PRESET=1
VK_LAYER_PRINTF_TO_STDOUT=1
(not always needed, but can help)
- if using
wgpu
, enablewgpu::Features::SPIRV_SHADER_PASSTHROUGH
, and usecreate_shader_module_passthrough
instead 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_module
calls withcreate_shader_module_passthrough
- enable
- in theory, the
VK_KHR_shader_non_semantic_info
Vulkan 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_settings
as aVK_LAYER_*
environment variables analogue, e.g.VK_LAYER_FOO
controlled by aVkLayerSettingEXT
with"foo"
aspSettingName
(and an appropriatetype
/value), included inVkLayerSettingsCreateInfoEXT
’spSettings
- on-disk configuration and interactive tooling, e.g.:
vk_layer_settings.txt
files, 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
debugPrintf
implementation, 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’
debugPrintf
support (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:
VkValidationFeaturesEXT
withpEnabledValidationFeatures
containingVK_VALIDATION_FEATURE_ENABLE_DEBUG_PRINTF_EXT
- env:
- enabled by one of (as per “general configurability” above):
- outputting the
debugPrintf
messages 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_utils
etc. - validation logging can itself be controlled via
VK_EXT_debug_utils
wgpu
built in debug mode (and/or with debug-assertions enabled):- it uses
VK_EXT_debug_utils
internally, exposing it vialog
- with e.g.
env_logger
,RUST_LOG=info
suffices fordebugPrintf
messages (as they specifically have the “info” level) - other
log
/tracing
subscribers should be configured similarly
- it uses
Fields
print_inputs: bool
Whether to also print the entry-point inputs (excluding buffers/resources), which should uniquely identify the panicking shader invocation.
print_backtrace: bool
Whether 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.