Shader: Add fallback for LDG from "ube" buffer ranges
We have a conversion from LDG on the compute shader to a special constant buffer binding that's used to exceed hardware limits on compute, but it was only running if the byte offset + constant buffer could be identified. The fallback that checks all of the bindings at runtime only checks the storage buffers.
This PR adds checking ube ranges to the LoadGlobal fallback. This extends the changes in #4011 to only check ube entries which are accessed by the shader, which saves adding useless bindings and checking them.
Fixes particles affected by the wind in The Legend of Zelda: Breath of the Wild, such as the grass particles. May fix other weird issues with compute shaders in some games.
Try a bunch of games and drivers to make sure they don't blow up loading constants willynilly from searchable buffers.
https://user-images.githubusercontent.com/6294155/205732462-cce718f3-18b6-44a4-85a0-85dbfb6fd30d.mp4
Here's the effect in question working.
Download the artifacts for this pull request:
- ryujinx-Release-1.1.0+dddfb33-linux_x64
- ryujinx-Release-1.1.0+dddfb33-osx_x64
- ryujinx-Release-1.1.0+dddfb33-win_x64
Experimental GUI (Avalonia)
GUI-less (SDL2)
Only for Developers
- ava-ryujinx-Debug-1.1.0+dddfb33-linux_x64
- ava-ryujinx-Debug-1.1.0+dddfb33-osx_x64
- ava-ryujinx-Debug-1.1.0+dddfb33-win_x64
- ryujinx-Debug-1.1.0+dddfb33-linux_x64
- ryujinx-Debug-1.1.0+dddfb33-osx_x64
- ryujinx-Debug-1.1.0+dddfb33-win_x64
- sdl2-ryujinx-headless-Debug-1.1.0+dddfb33-linux_x64
- sdl2-ryujinx-headless-Debug-1.1.0+dddfb33-osx_x64
- sdl2-ryujinx-headless-Debug-1.1.0+dddfb33-win_x64
Needs a rebase
Seems to cause a regression in Powerslave Exhumed. Crashes after proceeding into the second room of the first level.
00:00:29.595 |E| GPU.MainThread Application : Unhandled exception caught: System.NullReferenceException: Object reference not set to an instance of an object.
at Spv.Generator.Instruction.GetTotalWordCount()
at Spv.Generator.Instruction.Write(BinaryWriter writer)
at Spv.Generator.Module.Generate()
at Ryujinx.Graphics.Shader.CodeGen.Spirv.SpirvGenerator.Generate(StructuredProgramInfo info, ShaderConfig config)
at Ryujinx.Graphics.Shader.Translation.Translator.Translate(FunctionCode[] functions, ShaderConfig config)
at Ryujinx.Graphics.Shader.Translation.TranslatorContext.Translate(TranslatorContext other)
at Ryujinx.Graphics.Gpu.Shader.ShaderCache.TranslateShader(ShaderDumper dumper, GpuChannel channel, TranslatorContext context, Byte[] code)
at Ryujinx.Graphics.Gpu.Engine.Threed.StateUpdater.UpdateShaderState()
at Ryujinx.Graphics.Gpu.Engine.Threed.DrawManager.DrawEnd(ThreedClass engine, Int32 firstIndex, Int32 indexCount)
at Macro(MacroJitContext, IDeviceState, Int32)
at Ryujinx.Graphics.Gpu.Engine.GPFifo.GPFifoProcessor.Send(UInt64 gpuVa, Int32 offset, Int32 argument, Int32 subChannel, Boolean isLastCall)
at Ryujinx.Graphics.Gpu.Engine.GPFifo.GPFifoProcessor.Process(UInt64 baseGpuVa, ReadOnlySpan`1 commandBuffer)
at Ryujinx.Graphics.Gpu.Engine.GPFifo.GPFifoDevice.DispatchCalls()
at Ryujinx.Ui.RendererWidgetBase.<Render>b__75_0() in D:\a\Ryujinx\Ryujinx\Ryujinx\Ui\RendererWidgetBase.cs:line 425
at Ryujinx.Graphics.GAL.Multithreading.ThreadedRenderer.<>c__DisplayClass48_0.<RunLoop>b__0()
at System.Threading.Thread.StartCallback()
This is based off of an older version of master with this kind of bug in various games. Wait for it to be rebased first.
The branch has been rebased.
No longer crashes after rebase.