mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-09 17:11:32 -10:00
fix(proton): Windows games see only the cores they are pinned to
Game cores pinned the game with taskset, but Wine counts the online CPUs, so a game held to two cores still saw eight processors and sized its thread pools for them. Prototype freezes at its splash screen that way. When the session or a game profile limits the game cores, Wine now gets WINE_CPU_TOPOLOGY for exactly those cores unless the profile sets its own.
This commit is contained in:
1 parent
d905f03bf7
commit
9d85af7558
2 files changed
+32
No files matched your search
@@ -351,6 +351,20 @@ def game_cores(env):
|
||||
print("droiddeck-game-env: could not use game cores %r (%s)" % (text, error), file=sys.stderr)
|
||||
|
||||
|
||||
def cpu_topology(env):
|
||||
if env.get("WINE_CPU_TOPOLOGY") or not (env.get("DROIDDECK_GAME_CORES", "").strip() or env.get("BL_GAME_CPUS", "").strip()):
|
||||
return
|
||||
try:
|
||||
cores = sorted(os.sched_getaffinity(0))
|
||||
except OSError:
|
||||
return
|
||||
online = online_cores()
|
||||
if not cores or set(cores) >= online or cores[-1] >= len(online):
|
||||
return
|
||||
env["WINE_CPU_TOPOLOGY"] = "%d:%s" % (len(cores), ",".join(map(str, cores)))
|
||||
print("droiddeck-game-env: Windows sees %d cores (%s)" % (len(cores), env["WINE_CPU_TOPOLOGY"]), file=sys.stderr)
|
||||
|
||||
|
||||
def apply_config(env, config, app_id, fixes=None):
|
||||
if config.get("version") != 1:
|
||||
raise ValueError("unsupported environment configuration")
|
||||
@@ -627,6 +641,7 @@ def main():
|
||||
env = vram_cap(env)
|
||||
env = force_ssbs(command, env)
|
||||
game_cores(env)
|
||||
cpu_topology(env)
|
||||
try:
|
||||
xbox = runpy.run_path(str(Path(__file__).with_name("droiddeck-xbox")))
|
||||
except Exception as error:
|
||||
|
||||
@@ -449,6 +449,23 @@ class GameEnvironmentTest(unittest.TestCase):
|
||||
self.assertEqual(calls, [{0, 1, 2}])
|
||||
self.assertEqual(MODULE["parse_cores"]("0,2-7"), {0, 2, 3, 4, 5, 6, 7})
|
||||
|
||||
def test_windows_games_see_only_the_cores_they_are_pinned_to(self):
|
||||
os_mod = MODULE["os"]
|
||||
online = {"online_cores": lambda: {0, 1, 2, 3, 4, 5, 6, 7}}
|
||||
cases = [
|
||||
({"BL_GAME_CPUS": "6,7"}, {6, 7}, "2:6,7"),
|
||||
({"DROIDDECK_GAME_CORES": "0-2"}, {0, 1, 2}, "3:0,1,2"),
|
||||
({"BL_GAME_CPUS": "0-7"}, set(range(8)), None),
|
||||
({}, {6, 7}, None),
|
||||
({"BL_GAME_CPUS": "6,7", "WINE_CPU_TOPOLOGY": "4:0,1,2,3"}, {6, 7}, "4:0,1,2,3"),
|
||||
({"BL_GAME_CPUS": "9"}, {9}, None),
|
||||
]
|
||||
for env, affinity, expected in cases:
|
||||
with mock.patch.dict(MODULE["cpu_topology"].__globals__, online), \
|
||||
mock.patch.object(os_mod, "sched_getaffinity", return_value=affinity, create=True):
|
||||
MODULE["cpu_topology"](env)
|
||||
self.assertEqual(env.get("WINE_CPU_TOPOLOGY"), expected, env)
|
||||
|
||||
def test_caravan_sandwitch_robocop_and_cyberpunk_run_at_feature_level_12_1(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
caravan = Path(tmp) / "Caravan SandWitch"
|
||||
|
||||
Reference in new issue
Block a user