[PR #2448] [MERGED] shader_recompiler: Implement AMD buffer bounds checking behavior. #2741

Closed
opened 2026-02-27 22:01:04 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/shadps4-emu/shadPS4/pull/2448
Author: @squidbus
Created: 2/15/2025
Status: Merged
Merged: 2/17/2025
Merged by: @raphaelthegreat

Base: mainHead: buffer-bounds


📝 Commits (5)

  • c35bcad shader_recompiler: Implement AMD buffer bounds checking behavior.
  • 7c3c018 shader_recompiler: Use SRT flatbuf for bounds check size.
  • e7906f6 shader_recompiler: Fix buffer atomic bounds check.
  • 15a47d1 buffer_cache: Prevent false image-to-buffer sync.
  • a66adeb Address review comments.

📊 Changes

19 files changed (+377 additions, -159 deletions)

View changed files

📝 src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp (+25 -1)
📝 src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp (+133 -52)
📝 src/shader_recompiler/backend/spirv/emit_spirv_special.cpp (+1 -1)
📝 src/shader_recompiler/backend/spirv/spirv_emit_context.cpp (+73 -28)
📝 src/shader_recompiler/backend/spirv/spirv_emit_context.h (+6 -1)
📝 src/shader_recompiler/frontend/fetch_shader.cpp (+7 -2)
📝 src/shader_recompiler/frontend/fetch_shader.h (+2 -0)
📝 src/shader_recompiler/frontend/translate/translate.cpp (+58 -32)
📝 src/shader_recompiler/frontend/translate/translate.h (+2 -0)
📝 src/shader_recompiler/frontend/translate/vector_memory.cpp (+4 -0)
📝 src/shader_recompiler/info.h (+18 -12)
📝 src/shader_recompiler/ir/reg.h (+1 -0)
📝 src/shader_recompiler/profile.h (+1 -0)
📝 src/video_core/buffer_cache/buffer_cache.cpp (+5 -1)
📝 src/video_core/renderer_vulkan/vk_instance.cpp (+22 -17)
📝 src/video_core/renderer_vulkan/vk_instance.h (+13 -5)
📝 src/video_core/renderer_vulkan/vk_pipeline_cache.cpp (+1 -0)
📝 src/video_core/renderer_vulkan/vk_rasterizer.cpp (+0 -1)
📝 src/video_core/renderer_vulkan/vk_rasterizer.h (+5 -6)

📄 Description

Implements AMD buffer bounds checking behavior, in one of two ways:

  • Enables robustBufferAccess2 Vulkan feature where supported. This should provide equivalent buffer bounds checking behavior on its own. Have also added some logs for the presence of extension features we consider optional.
  • When the above is unsupported (MoltenVK is the only example I currently know of relevant to us), emulates buffer bounds checks in shader.
    • Buffer sizes are read from sharps in the SRT flatbuf, and buffer loads/stores/atomics are wrapped in comparisons checking indices against the size.
    • Vertex fetch shaders are inlined as normal buffer accesses instead of being converted to vertex bindings, so that they can be wrapped with bounds checks. As far as I know this part should not have much of a performance impact as Apple GPUs have no vertex fetch hardware similar to AMD, so they convert to regular buffers at the driver level.

I have found at least one game that needs this behavior, CUSA16404, in order to draw some 2D UI effects, particles, and flat geometry. It seems the game has a bug where it does an instanced draw with vertex buffers sized to the number of instances, and for some reason a single one of the vertex attributes is indexed by vertex ID instead of instance ID like the others. This may not have been caught in development as the value is usually zero, so with bounds checking it works.

This may also help reduce some device losses and other weird GPU corruption behavior on macOS, as previously there was no buffer robustness at all, allowing misbehaving games to trash things and cause faults.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/shadps4-emu/shadPS4/pull/2448 **Author:** [@squidbus](https://github.com/squidbus) **Created:** 2/15/2025 **Status:** ✅ Merged **Merged:** 2/17/2025 **Merged by:** [@raphaelthegreat](https://github.com/raphaelthegreat) **Base:** `main` ← **Head:** `buffer-bounds` --- ### 📝 Commits (5) - [`c35bcad`](https://github.com/shadps4-emu/shadPS4/commit/c35bcad851fc6b8217d058a50f4f86cb004ceab6) shader_recompiler: Implement AMD buffer bounds checking behavior. - [`7c3c018`](https://github.com/shadps4-emu/shadPS4/commit/7c3c0183e9bc3f8ae1ce1d162f589ff39a1c9004) shader_recompiler: Use SRT flatbuf for bounds check size. - [`e7906f6`](https://github.com/shadps4-emu/shadPS4/commit/e7906f603e55d88bd364863bbccdfa7629108a8a) shader_recompiler: Fix buffer atomic bounds check. - [`15a47d1`](https://github.com/shadps4-emu/shadPS4/commit/15a47d10ae9913bb74a58827e8580f9c4822da32) buffer_cache: Prevent false image-to-buffer sync. - [`a66adeb`](https://github.com/shadps4-emu/shadPS4/commit/a66adebe1bb595416a80347434cfb3d1b2ab1134) Address review comments. ### 📊 Changes **19 files changed** (+377 additions, -159 deletions) <details> <summary>View changed files</summary> 📝 `src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp` (+25 -1) 📝 `src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp` (+133 -52) 📝 `src/shader_recompiler/backend/spirv/emit_spirv_special.cpp` (+1 -1) 📝 `src/shader_recompiler/backend/spirv/spirv_emit_context.cpp` (+73 -28) 📝 `src/shader_recompiler/backend/spirv/spirv_emit_context.h` (+6 -1) 📝 `src/shader_recompiler/frontend/fetch_shader.cpp` (+7 -2) 📝 `src/shader_recompiler/frontend/fetch_shader.h` (+2 -0) 📝 `src/shader_recompiler/frontend/translate/translate.cpp` (+58 -32) 📝 `src/shader_recompiler/frontend/translate/translate.h` (+2 -0) 📝 `src/shader_recompiler/frontend/translate/vector_memory.cpp` (+4 -0) 📝 `src/shader_recompiler/info.h` (+18 -12) 📝 `src/shader_recompiler/ir/reg.h` (+1 -0) 📝 `src/shader_recompiler/profile.h` (+1 -0) 📝 `src/video_core/buffer_cache/buffer_cache.cpp` (+5 -1) 📝 `src/video_core/renderer_vulkan/vk_instance.cpp` (+22 -17) 📝 `src/video_core/renderer_vulkan/vk_instance.h` (+13 -5) 📝 `src/video_core/renderer_vulkan/vk_pipeline_cache.cpp` (+1 -0) 📝 `src/video_core/renderer_vulkan/vk_rasterizer.cpp` (+0 -1) 📝 `src/video_core/renderer_vulkan/vk_rasterizer.h` (+5 -6) </details> ### 📄 Description Implements AMD buffer bounds checking behavior, in one of two ways: * Enables `robustBufferAccess2` Vulkan feature where supported. This should provide equivalent buffer bounds checking behavior on its own. Have also added some logs for the presence of extension features we consider optional. * When the above is unsupported (MoltenVK is the only example I currently know of relevant to us), emulates buffer bounds checks in shader. * Buffer sizes are read from sharps in the SRT flatbuf, and buffer loads/stores/atomics are wrapped in comparisons checking indices against the size. * Vertex fetch shaders are inlined as normal buffer accesses instead of being converted to vertex bindings, so that they can be wrapped with bounds checks. As far as I know this part should not have much of a performance impact as Apple GPUs have no vertex fetch hardware similar to AMD, so they convert to regular buffers at the driver level. I have found at least one game that needs this behavior, CUSA16404, in order to draw some 2D UI effects, particles, and flat geometry. It seems the game has a bug where it does an instanced draw with vertex buffers sized to the number of instances, and for some reason a single one of the vertex attributes is indexed by vertex ID instead of instance ID like the others. This may not have been caught in development as the value is usually zero, so with bounds checking it works. This may also help reduce some device losses and other weird GPU corruption behavior on macOS, as previously there was no buffer robustness at all, allowing misbehaving games to trash things and cause faults. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
kerem 2026-02-27 22:01:04 +03:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/shadPS4#2741
No description provided.