Material::specialize
is provided an incomplete set of engine-sourced shader definitions
#8190
Labels
A-Rendering
Drawing game state to the screen
C-Bug
An unexpected or incorrect behavior
D-Modest
A "normal" level of difficulty; suitable for simple features or challenging fixes
S-Ready-For-Implementation
This issue is ready for an implementation PR. Go for it!
Bevy version
v0.10.0
Relevant system information
What you did
Material
typeMaterial::specialize
, inspected the contents ofVertexState::shader_defs
andFragmentState::shader_defs
to determine which definitions would be active inside the respective shaders.What went wrong
NO_ARRAY_TEXTURES_SUPPORT
,SIXTEEN_BYTE_ALIGNMENT
, andAVAILABLE_STORAGE_BUFFER_BINDINGS
activate in shaders, but do not appear in eithershader_defs
vector.Material
in question from reasoning about the state of certain mesh view bindings with respect to its shaders, such as point lights, cluster information, and globals.Additional information
The definitions in question are injected into the
shader_defs
vector that gets passed toShaderProcessor::process
inShaderCache::get
.This occurs after
Material::specialize
, which is part of theSpecialized*Pipeline::specialize
call hierarchy - the entirety of which is also subject to the issue in question - and originates in various render world systems related to concrete implementations of those traits.This does not match the lifecycle of the data that drives these definitions.
NO_ARRAY_TEXTURES_SUPPORT
andSIXTEEN_BYTE_ALIGNMENT
are conditional over thewebgl
feature flag, andAVAILABLE_STORAGE_BUFFER_BINDINGS
is driven bywgpu::Limits::max_storage_buffers_per_shader_stage
.Neither of these will change over the course of the program, so there is no intrinsic reason to reconstruct them whenever
ShaderCache::get
is called. In addition to creating a consistency problem, this is spending CPU time where memory could do the job.Furthermore, the data used to construct said definitions is freely available from the language and ECS respectively. This encourages affected users to duplicate bevy-internal code, violating the DRY principle and creating brittle points of failure should the definitions or logic behind them change in a future engine version.
This can be fixed by introducing some form of top-level definition storage to the specialization trait / call hierarchy, and providing access so members of the tree can construct their definition sets from it.
Related
Incidental: #7771
ShaderCache
's late-injection behaviour was previously preventing the use of SPIR-V byMaterial
implementors, asShaderProcessor
was checking theshader_defs
vector for zero-length (as it does not support processing binary) and returning an error.The
ShaderProcessor
issue was initially addressed by opening #7772, but discussion with @superdump on Discord (documented here for issue tracker transparency) concluded that the definitions in question should be made available toMaterial
, so they could be manually cleared by the user. To this end, #7903 was opened as an alternate solution with the intent of providing a more idiomatic fix.Recently #7772 was merged (closing #7771), presumably as an intermediary measure to remove the blocker for SPIR-V users. No comment was made with respect to the state of #7903, so it can be assumed that the intent is still to fix the issue in a robust way, as originally discussed.
#7903 was reviewed by @superdump re. potential footgun caused by moving said defs into a free function and requiring
Specialized*Pipeline
implementors to call it, which was addressed by moving them to a member insidePipelineCache
- of whichShaderCache
is a member - and extending the*::specialize
trait hierarchy with a newshader_defs
input, mutated in lieu of constructing an empty vec by existing implementors.Further discussion with @robtfm in #7903 indicates adding a base
shader_defs
member toPipelineCache
for this purpose is undesirable, as is introducing aBaseShaderDefs
newtype resource to be consumed in applicable render systems, and extending the*::specialize
hierarchy with a new parameter. That would leave static storage (i.e.Lazy
), or some yet-to-be determined mechanism that satisfies the various requirements.This issue has been opened to enumerate the problem in full context, act as an anchor for the previously free-floating #7903, and open discussion on a desirable approach to fixing it.
The text was updated successfully, but these errors were encountered: