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) <noreply@anthropic.com>
This commit is contained in:
Henrik RydgårdandClaude Opus 5.5 committed 2026-10-09 11:39:29 +02:00
1 parent 9ce774d9f9
commit 8a7a67ae25
1 file changed
+7 -8
+7 -8
View File
@@ -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;