From 8a7a67ae25c77e89bbaa9483d7ccda52e2fce548 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 5 Oct 2026 14:40:24 -0600 Subject: [PATCH] SoftGPU: Use larger tiles now that pixels are cheaper With the span drawing and sampling faster, the setup a triangle repeats for each tile it touches weighs more, so the rule is now eight tiles per thread instead of sixteen (64x32 on eight threads). Against sixteen, in wall time on five games: God of War -2.6%, Wipeout -1.7%, LocoRoco -5.2%, Tekken 6 -5.6%, Burnout -3.3%, with 2.5-8% less CPU. Four per thread used the least CPU but was slower than eight in wall time in most of them. Co-Authored-By: Claude Opus 5.5 (1M context) --- GPU/Software/BinManager.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/GPU/Software/BinManager.cpp b/GPU/Software/BinManager.cpp index c4d637b0cf..b6c76ece3f 100644 --- a/GPU/Software/BinManager.cpp +++ b/GPU/Software/BinManager.cpp @@ -1106,20 +1106,19 @@ bool BinManager::NeedsOrder(const BinItem &item) { return false; } -// Each extra tile a triangle touches sets it up again, so tiles are as large as they can be with plenty to -// spare for every thread: at least sixteen per thread over a 480x272 screen. With fewer, a scene whose -// drawing is concentrated on part of the screen leaves threads idle (LocoRoco took a third longer with four -// per thread on eight threads). +// Each extra tile a triangle touches sets it up again, so tiles are as large as they can be with enough to +// spare for every thread: at least eight per thread over a 480x272 screen (64x32 on eight threads). With +// fewer, a scene whose drawing is concentrated on part of the screen leaves threads idle: four per thread +// used the least CPU but took longer in wall time than eight in most games, Wipeout longer than sixteen. // The multiplier trades the repeated setup against the load balance, so the best one depends on what drawing -// a pixel costs. When that gets cheaper, larger tiles can win: with faster span drawing, four per thread was -// as fast in wall time and used less CPU. Measure again (Tools/headless_bench.py, wall and CPU time on -// several games) after changes to the per-pixel cost. +// a pixel costs (sixteen was best before the span drawing got faster). Measure again +// (Tools/headless_bench.py, wall and CPU time on several games) after changes to the per-pixel cost. void BinManager::PickTileSize(int threads) { static const int sizes[][2] = { { 128, 32 }, { 64, 32 }, { 64, 16 } }; int w = MIN_TILE_W, h = MIN_TILE_H; for (const auto &size : sizes) { const int tiles = ((480 + size[0] - 1) / size[0]) * ((272 + size[1] - 1) / size[1]); - if (tiles >= 16 * threads) { + if (tiles >= 8 * threads) { w = size[0]; h = size[1]; break;