Repository navigation
Conversation
|
Retargeted to |
c0c19b4 to
c5be508
Compare
8a5c8c4 to
6575f29
Compare
Switch 2 games ship their native Ampere programs verbatim in shader containers (BNSH, agl BAHS, effect and layout archives). Each program ends with a branch to itself, and a graphics program starts 0x80 bytes into a 256-byte block that holds its program header. The scanner finds the programs from those markers and checks each one with the same capture the runtime uses, so it reads the code the runtime would read. BNSH and agl program tables also tell which vertex and pixel programs form a shader program, and BNSH tables lead to the NVN shader control section that holds a compute program's workgroup and shared memory sizes. Nothing uses the scanner yet. Assisted-by: Claude Opus 5.5 (investigation and implementation) Signed-off-by: failaip12 <86018517+failaip12@users.noreply.github.com>
Move the part of LowerNativeCode that builds the cached code (program header, lowered instructions with scheduling words, native address map) into MakeLoweredNativeCode, so programs read from the game's files get the same code and shader hash as the ones captured at bind. No functional change. Assisted-by: Claude Opus 5.5 (investigation and implementation) Signed-off-by: failaip12 <86018517+failaip12@users.noreply.github.com>
ScannedEnvironment translates a native program before the game binds it. Translation reads GPU state the program only sees once bound, so it answers with what nearly all programs read: 2D textures with float formats, mapped storage pointers and zero for constant buffer values. Compute programs take their workgroup and shared memory sizes from the caller. Assisted-by: Claude Opus 5.5 (investigation and implementation) Signed-off-by: failaip12 <86018517+failaip12@users.noreply.github.com>
Add the per-game "Precompile shaders (Switch 2)" setting, off by default. When it is on and the disk shader cache is too, booting a Switch 2 game scans the RomFS the game reads (update and mods applied) for native programs on a background thread while the pipeline cache loads, and hands the programs, their vertex and pixel pairs and the compute dispatch sizes to the rasterizer. The RomFS is opened only when the rasterizer will use the programs. The scan bounds its reads and skips media files. The list is cached beside the pipeline cache as native_programs.bin, checked when read back and kept while the RomFS keeps the same file names and sizes, so later boots skip the scan. No rasterizer uses it yet. Assisted-by: Claude Opus 5.5 (investigation and implementation) Signed-off-by: failaip12 <86018517+failaip12@users.noreply.github.com>
…ng screen Switch 2 games stutter for a long time the first time new tracks and effects are drawn, because each new pipeline is compiled then. At the end of the loading screen, build a pipeline for each vertex and pixel pair of the game's files, and drop it again. The driver keeps what it compiled, so the game's own pipelines are ready when first drawn. Graphics pipelines copy the fixed state of the title's recorded pipelines: the render setups enough of them use, each with the shader state most of its pipelines have, and the vertex attribute types they record, with the combinations that differ (integer bone indices) for the vertex programs that read them. Compute programs are built with the workgroup and shared memory sizes from their control sections; they need no recorded state, so they are built on a first boot too. Built and rejected pipelines are listed in precompiled.bin, written after the Vulkan cache file holds them and at checkpoints spaced by that file's size, so later boots build only what is new. What the first pass finds in each program is kept in precompile_programs.bin. Both name the cache version, the emulator build, the device, the driver and the dynamic state, and are redone when any changes. Every step is logged in precompile_running.bin before and after it runs: a step that a boot did not finish, or that the driver failed to build, is tried once more and then skipped, so a crashing driver does not crash every boot. Without the Vulkan pipeline cache and without a driver that keeps pipelines, nothing is precompiled. The precompile lives in vk_pipeline_precompile.cpp. Its builds run on as many threads as runtime builds and stay out of the slow-build log. Assisted-by: Claude Opus 5.5 (investigation and implementation) Signed-off-by: failaip12 <86018517+failaip12@users.noreply.github.com>
92f47fe to
748d713
Compare
|
Good timing as that's something I am working on right now. Will have to do an A/B test to see how many compute shaders your approach detects versus my current one (which should also resolve #714 and #121). Found approach for compiling all the shaders seems a little unintuitive but will need testing to see what we can do about that. |
|
Included in #825 , still have to check if anything crucial is missing from here before merging/closing the PR. |
Considering that should i stop changing this pr then, cause i was planning to do some windows testing and try some other games and fix any issues i find. |
Summary
Adds a experimental toggle to precompile shaders.
It currently works in a weird way due to it needing a recorded pipeline cache. It needs the user to toggle the option first, run the game which will precompile the compute shaders, play at least one track, restart the game, and only then will the full recompilation process start.
This can be fixed by bundling the game specific render setups(recorded pipeline cache) which should be fine legally but is kinda close to bundling precompiled shaders so this is not done here.
This is a draft as windows and intel configurations are not tested, only MKW was tested and i am unsure of the stability of this right now.
Type of change
Related issues
Works best with #812 (cache folder for Mario Kart World).
On RADV, precompiled pipelines are currently kept in Eglantine's vulkan_pipelines.bin; with #714 they would live in Mesa's shader cache instead.
May help with first-play shader stutter reported in #121.
Testing
Games tested:
Tested on MKW 1.8.0 on Linux wiith nvidia and linux with amd gpu.
Nvidia shaders took much longer to build than AMD ones.
Checklist
Screenshots / logs
Claude Opus 5.5 was used for the investigation and the implementation.
Assisted-by: Claude Opus 5.5 (investigation and implementation)