Metal: Hardware texture scaling

Runs the same compute shaders as the Vulkan backend, translated to MSL,
in the upload command buffer: levels decode unscaled into the push
buffer and get scaled into a view of the level. Push constants go in a
buffer of their own. Multipass shaders (NNEDI3) use scratch textures
that live for the frame.

Shaders with a constant buffer (only the smiley test shader) aren't
supported.

All the texture shaders give the same result as Vulkan's on LocoRoco
and God of War savestates.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-19 12:02:22 +02:00
1 parent 55109b39fb
commit b2e6113f21
5 files changed
+304 -6

No files matched your search

+2 -3
View File
@@ -163,8 +163,7 @@ void GameSettingsScreen::PreCreateViews() {
}
static bool UsingHardwareTextureScaling() {
// For now, Vulkan only.
return g_Config.bTexHardwareScaling && GetGPUBackend() == GPUBackend::VULKAN && !g_Config.bSoftwareRendering;
return g_Config.bTexHardwareScaling && (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::METAL) && !g_Config.bSoftwareRendering;
}
static std::string TextureTranslateName(std::string_view value) {
@@ -519,7 +518,7 @@ void GameSettingsScreen::CreateGraphicsSettings(UI::ViewGroup *graphicsSettings)
graphicsSettings->Add(new ItemHeader(gr->T("Texture upscaling")));
if (GetGPUBackend() == GPUBackend::VULKAN) {
if (GetGPUBackend() == GPUBackend::VULKAN || GetGPUBackend() == GPUBackend::METAL) {
ChoiceWithValueDisplay *textureShaderChoice = graphicsSettings->Add(new ChoiceWithValueDisplay(&g_Config.sTextureShaderName, gr->T("GPU texture upscaler (fast)"), &TextureTranslateName));
textureShaderChoice->OnClick.Add([this](UI::EventParams &e) {
auto gr = GetI18NCategory(I18NCat::GRAPHICS);