mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
Android: expose GS Multi-threading (GV7 back-thread) in settings + in-game menu
Off/On toggle (On = Pipelined, enum 3) for GSBackThreadMode, default Off: - Renderer settings tab, under the graphics-API/driver picker - In-game quick menu (Graphics), grouped with renderer + Apply & Restart (MenuSwitchRow gains an optional inline description) - Settings model with per-game override, i18n strings, search index entry - native-lib snapshots the field across a live settings apply so the restart-required option can't trigger a mid-game device recreate
This commit is contained in:
@@ -1334,6 +1334,7 @@ Java_kr_co_iefriends_pcsx2_NativeApp_applyGSSettingsLive(JNIEnv *env, jclass cla
|
||||
const auto saved_no_vs_expand = EmuConfig.GS.DisableVertexShaderExpand;
|
||||
const auto saved_tex_barriers = EmuConfig.GS.OverrideTextureBarriers;
|
||||
const auto saved_depth_feedback = EmuConfig.GS.DepthFeedbackMode;
|
||||
const auto saved_back_thread = EmuConfig.GS.BackThreadMode;
|
||||
const auto saved_hwaa1 = EmuConfig.GS.HWAA1;
|
||||
const auto saved_exclusive_fs = EmuConfig.GS.ExclusiveFullscreenControl;
|
||||
const auto saved_sw_threads = EmuConfig.GS.SWExtraThreads;
|
||||
@@ -1361,6 +1362,7 @@ Java_kr_co_iefriends_pcsx2_NativeApp_applyGSSettingsLive(JNIEnv *env, jclass cla
|
||||
EmuConfig.GS.DisableVertexShaderExpand = saved_no_vs_expand;
|
||||
EmuConfig.GS.OverrideTextureBarriers = saved_tex_barriers;
|
||||
EmuConfig.GS.DepthFeedbackMode = saved_depth_feedback;
|
||||
EmuConfig.GS.BackThreadMode = saved_back_thread;
|
||||
EmuConfig.GS.HWAA1 = saved_hwaa1;
|
||||
EmuConfig.GS.ExclusiveFullscreenControl = saved_exclusive_fs;
|
||||
EmuConfig.GS.SWExtraThreads = saved_sw_threads;
|
||||
|
||||
@@ -263,6 +263,10 @@ data class Settings(
|
||||
val useAngleOpenGL: Boolean = false,
|
||||
/** EmuCore/GS/OverrideTextureBarriers — -1 Auto / 0 Off / 1 On. */
|
||||
val overrideTextureBarriers: Int = -1,
|
||||
/** EmuCore/GS/GSBackThreadMode — GV7 GS front/back thread split.
|
||||
* 0 Off (single-threaded), 1 Inline, 2 Lockstep, 3 Pipelined (fastest).
|
||||
* Defaults to Off (opt-in); a per-game override can raise it. Restart-required. */
|
||||
val gsBackThreadMode: Int = 0,
|
||||
/** EmuCore/GS/DisableVertexShaderExpand — force CPU vertex expansion. Renderer-init; restart to apply. */
|
||||
val disableVertexShaderExpand: Boolean = false,
|
||||
/** EmuCore/GS/UseBlitSwapChain — blit present model instead of flip. Renderer-init; restart to apply. */
|
||||
@@ -1066,6 +1070,7 @@ data class Settings(
|
||||
forceMaliFbFetch = boolAt("EmuCore/GS/ForceMaliFramebufferFetch") ?: this.forceMaliFbFetch,
|
||||
useAngleOpenGL = boolAt("EmuCore/GS/AndroidUseAngleOpenGL") ?: this.useAngleOpenGL,
|
||||
overrideTextureBarriers = intAt("EmuCore/GS/OverrideTextureBarriers") ?: this.overrideTextureBarriers,
|
||||
gsBackThreadMode = intAt("EmuCore/GS/GSBackThreadMode") ?: this.gsBackThreadMode,
|
||||
disableVertexShaderExpand = boolAt("EmuCore/GS/DisableVertexShaderExpand") ?: this.disableVertexShaderExpand,
|
||||
useBlitSwapChain = boolAt("EmuCore/GS/UseBlitSwapChain") ?: this.useBlitSwapChain,
|
||||
disableShaderCache = boolAt("EmuCore/GS/DisableShaderCache") ?: this.disableShaderCache,
|
||||
@@ -1256,6 +1261,7 @@ data class Settings(
|
||||
// reflects the toggle.
|
||||
put("EmuCore/GS", "AndroidUseAngleOpenGL", "bool", useAngleOpenGL.toString())
|
||||
put("EmuCore/GS", "OverrideTextureBarriers", "int", overrideTextureBarriers.coerceIn(-1, 1).toString())
|
||||
put("EmuCore/GS", "GSBackThreadMode", "int", gsBackThreadMode.coerceIn(0, 3).toString())
|
||||
put("EmuCore/GS", "DisableVertexShaderExpand", "bool", disableVertexShaderExpand.toString())
|
||||
put("EmuCore/GS", "UseBlitSwapChain", "bool", useBlitSwapChain.toString())
|
||||
put("EmuCore/GS", "DisableShaderCache", "bool", disableShaderCache.toString())
|
||||
@@ -1487,6 +1493,7 @@ data class Settings(
|
||||
put("forceMaliFbFetch", forceMaliFbFetch)
|
||||
put("useAngleOpenGL", useAngleOpenGL)
|
||||
put("overrideTextureBarriers", overrideTextureBarriers)
|
||||
put("gsBackThreadMode", gsBackThreadMode)
|
||||
put("disableVertexShaderExpand", disableVertexShaderExpand)
|
||||
put("useBlitSwapChain", useBlitSwapChain)
|
||||
put("disableShaderCache", disableShaderCache)
|
||||
@@ -1732,6 +1739,7 @@ data class Settings(
|
||||
forceMaliFbFetch = json.optBoolean("forceMaliFbFetch", def.forceMaliFbFetch),
|
||||
useAngleOpenGL = json.optBoolean("useAngleOpenGL", def.useAngleOpenGL),
|
||||
overrideTextureBarriers = json.optInt("overrideTextureBarriers", def.overrideTextureBarriers),
|
||||
gsBackThreadMode = json.optInt("gsBackThreadMode", def.gsBackThreadMode),
|
||||
disableVertexShaderExpand = json.optBoolean("disableVertexShaderExpand", def.disableVertexShaderExpand),
|
||||
useBlitSwapChain = json.optBoolean("useBlitSwapChain", def.useBlitSwapChain),
|
||||
disableShaderCache = json.optBoolean("disableShaderCache", def.disableShaderCache),
|
||||
@@ -1961,6 +1969,7 @@ data class Settings(
|
||||
if (current.forceMaliFbFetch != base.forceMaliFbFetch) j.put("forceMaliFbFetch", current.forceMaliFbFetch)
|
||||
if (current.useAngleOpenGL != base.useAngleOpenGL) j.put("useAngleOpenGL", current.useAngleOpenGL)
|
||||
if (current.overrideTextureBarriers != base.overrideTextureBarriers) j.put("overrideTextureBarriers", current.overrideTextureBarriers)
|
||||
if (current.gsBackThreadMode != base.gsBackThreadMode) j.put("gsBackThreadMode", current.gsBackThreadMode)
|
||||
if (current.disableVertexShaderExpand != base.disableVertexShaderExpand) j.put("disableVertexShaderExpand", current.disableVertexShaderExpand)
|
||||
if (current.useBlitSwapChain != base.useBlitSwapChain) j.put("useBlitSwapChain", current.useBlitSwapChain)
|
||||
if (current.disableShaderCache != base.disableShaderCache) j.put("disableShaderCache", current.disableShaderCache)
|
||||
@@ -2173,6 +2182,7 @@ data class Settings(
|
||||
forceMaliFbFetch = if (overrides.has("forceMaliFbFetch")) overrides.getBoolean("forceMaliFbFetch") else base.forceMaliFbFetch,
|
||||
useAngleOpenGL = if (overrides.has("useAngleOpenGL")) overrides.getBoolean("useAngleOpenGL") else base.useAngleOpenGL,
|
||||
overrideTextureBarriers = if (overrides.has("overrideTextureBarriers")) overrides.getInt("overrideTextureBarriers") else base.overrideTextureBarriers,
|
||||
gsBackThreadMode = if (overrides.has("gsBackThreadMode")) overrides.getInt("gsBackThreadMode") else base.gsBackThreadMode,
|
||||
disableVertexShaderExpand = if (overrides.has("disableVertexShaderExpand")) overrides.getBoolean("disableVertexShaderExpand") else base.disableVertexShaderExpand,
|
||||
useBlitSwapChain = if (overrides.has("useBlitSwapChain")) overrides.getBoolean("useBlitSwapChain") else base.useBlitSwapChain,
|
||||
disableShaderCache = if (overrides.has("disableShaderCache")) overrides.getBoolean("disableShaderCache") else base.disableShaderCache,
|
||||
|
||||
@@ -992,6 +992,8 @@ val EN: Map<String, String> = mapOf(
|
||||
"renderer.gamma.label" to "Gamma",
|
||||
"renderer.gpuProfile.description" to "Overrides Android GPU workaround selection. Auto is recommended.",
|
||||
"renderer.gpuProfile.label" to "GPU Profile",
|
||||
"renderer.gsBackThread.label" to "GS Multi-threading",
|
||||
"renderer.gsBackThread.description" to "Off by default. Runs GS rendering on a second thread so you can push 2x/3x internal resolution without the frame dips. If a game shows graphics glitches, turn it back off (can be set per-game). Restart the game to apply.",
|
||||
"renderer.gsDump.description" to "Saves one frame of GPU commands (.gs) to the snaps folder — replayable in desktop PCSX2 to diagnose rendering bugs.",
|
||||
"renderer.gsDump.label" to "Capture GS Dump (bug report)",
|
||||
"renderer.gsDump.queued" to "GS dump queued — close this menu so it captures the frame. Saved to the snaps folder.",
|
||||
|
||||
@@ -577,6 +577,18 @@ private fun GraphicsPane(state: EmulationMenuUiState, viewModel: EmulationMenuVi
|
||||
viewModel.updateSettings { it.copy(useAngleOpenGL = on) }
|
||||
}
|
||||
}
|
||||
// GS Multi-threading (GV7 front/back split). Restart-required like the renderer /
|
||||
// driver above, so it lives in the same group — hit Apply & Restart below to apply.
|
||||
// Off = single-threaded; On = GS on a dedicated back thread (Pipelined, enum 3).
|
||||
// The Inline/Lockstep dev rungs are not exposed. Description shown inline so users
|
||||
// who never open full settings still understand what it does.
|
||||
MenuSwitchRow(
|
||||
str("renderer.gsBackThread.label"),
|
||||
settings.gsBackThreadMode >= 3,
|
||||
description = str("renderer.gsBackThread.description"),
|
||||
) { on ->
|
||||
viewModel.updateSettings { it.copy(gsBackThreadMode = if (on) 3 else 0) }
|
||||
}
|
||||
CompactAction(str("backend.applyRestart"), "↻", Modifier.fillMaxWidth(), MainActivityRuntime::restart)
|
||||
HorizontalOptions(
|
||||
title = str("renderer.upscale.label"),
|
||||
@@ -1179,6 +1191,7 @@ private fun MenuSwitchRow(
|
||||
title: String,
|
||||
checked: Boolean,
|
||||
enabled: Boolean = true,
|
||||
description: String? = null,
|
||||
onCheckedChange: (Boolean) -> Unit,
|
||||
) {
|
||||
Surface(
|
||||
@@ -1200,13 +1213,22 @@ private fun MenuSwitchRow(
|
||||
Modifier.padding(horizontal = 13.dp, vertical = 9.dp),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
title,
|
||||
modifier = Modifier.weight(1f),
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = if (enabled) MaterialTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 2,
|
||||
)
|
||||
Column(Modifier.weight(1f)) {
|
||||
Text(
|
||||
title,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = if (enabled) MaterialTheme.colorScheme.onSurface else MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 2,
|
||||
)
|
||||
if (description != null) {
|
||||
Text(
|
||||
description,
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant,
|
||||
maxLines = 3,
|
||||
)
|
||||
}
|
||||
}
|
||||
Spacer(Modifier.width(10.dp))
|
||||
Switch(checked = checked, onCheckedChange = if (enabled) onCheckedChange else null)
|
||||
}
|
||||
|
||||
@@ -107,6 +107,21 @@ fun RendererTab(state: MutableState<Settings>) {
|
||||
// from the removed first-run setup renderer page into settings.
|
||||
RendererBackendSection(state)
|
||||
SettingsDivider()
|
||||
// GS Multi-threading (GV7 front/back split), placed right under the
|
||||
// renderer/driver picker. Off = today's single-threaded path (the
|
||||
// default — opt-in); On = the GS runs on a dedicated back thread
|
||||
// (Pipelined, enum value 3). The enum's Inline/Lockstep rungs (1/2)
|
||||
// are dev-only and deliberately not exposed. Restart-required (in
|
||||
// RestartOptionsAreEqual); native-lib snapshots the field across a
|
||||
// live apply, so it only takes effect on the next game boot.
|
||||
ToggleRow(
|
||||
str("renderer.gsBackThread.label"),
|
||||
s.gsBackThreadMode >= 3,
|
||||
description = str("renderer.gsBackThread.description"),
|
||||
) {
|
||||
apply(s.copy(gsBackThreadMode = if (it) 3 else 0))
|
||||
}
|
||||
SettingsDivider()
|
||||
val upscaleIndex = UPSCALE_OPTIONS
|
||||
.indexOfFirst { abs(it.value - s.upscaleFloat) < 0.01f }
|
||||
.takeIf { it >= 0 } ?: 0
|
||||
|
||||
@@ -67,6 +67,7 @@ internal val SETTINGS_SEARCH_INDEX: List<SettingsSearchEntry> = listOf(
|
||||
SettingsSearchEntry("perf.advancedSpeedhacks.title", true, SettingsCategory.Performance),
|
||||
SettingsSearchEntry("VSync", false, SettingsCategory.Graphics),
|
||||
SettingsSearchEntry("renderer.shadeboost.label", true, SettingsCategory.Graphics),
|
||||
SettingsSearchEntry("renderer.gsBackThread.label", true, SettingsCategory.Graphics),
|
||||
SettingsSearchEntry("renderer.fxaa.label", true, SettingsCategory.Graphics),
|
||||
SettingsSearchEntry("renderer.shaderChain.label", true, SettingsCategory.Graphics),
|
||||
SettingsSearchEntry("renderer.shaderChain.preset.label", true, SettingsCategory.Graphics),
|
||||
|
||||
Reference in New Issue
Block a user