Support scalar replacement of large structs #6019
Open
+127
−9
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes an issue where structs with over 100 member variables are not fully optimized by the default performance recipe. This is due to the default performance recipe initializing the scalar replacement pass using a default size limit of a maximum of 100 struct/array members as opposed to the infinite size limit explicitly requested by the size and legalization passes.
Failure to fully apply scalar replacement prevents effective optimization of shaders that access small portions of large structs. This leads to optimizable code related to accesses of such structs being left unmodified, resulting in large SPIR-V binaries and poor performance on some GPUs. Not applying these optimizations was found to have a substantial effect on performance in a number of production shaders from real-world game titles, so it makes sense to follow the lead of the legalization and size recipes and also remove this limit from the default performance recipe.
With this PR, the default value for the default performance pass recipe, the ScalarReplacementPass constructor, and CreateScalarReplacementPass are updated to zero to remove the current size limit of 100.
This PR includes a test based on a simplified version of the real-world production shader that uses a struct with ~180 members where this issue was first identified. This test aims to ensure that in the future running the default performance recipe on a similar shader will produce SPIR-V code that will not benefit from further scalar replacement with no limit.