Parallel rendering pipeline, ring vertex buffer, phase timings
Five optimizations measured on the 100k-entity stress scene (Release, vsync off): 103 FPS baseline -> 297 FPS. - Sprite submission and vertex building run on all cores above Renderer2DOptions.ParallelThreshold (default 8192). Work is sliced into 4096-entity segments: a Friflo chunk holds a whole archetype, so per-chunk parallelism degenerates to one thread. Segments merge in deterministic order, preserving radix sort stability. - Vertex buffer is ring-written with SetDataOptions.NoOverwrite (GPU buffer 2x frame size); Discard only on wrap-around. - Texture2DRegion precomputes UVs - four float divisions per sprite per frame removed. - Renderer2D exposes per-phase timings (submit/sort/build/upload/draw), shown in the sample HUD - all further optimization is data-driven. - Sample BounceSystem parallelized the same segmented way. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
af319d1276
commit
e06f24a319
@@ -99,6 +99,53 @@ public class SpriteBatcherTests
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ChunkedSubmit_MergesInChunkOrder_AndCountsCulled()
|
||||
{
|
||||
var batcher = new SpriteBatcher();
|
||||
var key = SpriteSortKey.Make(0, 0f, 0); // одинаковый ключ — порядок задаётся слиянием чанков
|
||||
|
||||
batcher.BeginChunks([3, 2]);
|
||||
|
||||
var writer1 = batcher.GetChunkWriter(1); // чанки могут заполняться в любом порядке (параллельно)
|
||||
writer1.Add(Instance(10), key);
|
||||
writer1.AddCulled();
|
||||
batcher.EndChunk(1, in writer1);
|
||||
|
||||
var writer0 = batcher.GetChunkWriter(0);
|
||||
writer0.Add(Instance(1), key);
|
||||
writer0.Add(Instance(2), key);
|
||||
batcher.EndChunk(0, in writer0);
|
||||
|
||||
var accepted = batcher.CommitChunks();
|
||||
|
||||
Assert.Equal(3, accepted);
|
||||
Assert.Equal(1, batcher.LastChunkCulled);
|
||||
var order = batcher.Sort();
|
||||
Assert.Equal(1, batcher[order[0]].Layer); // сначала чанк 0...
|
||||
Assert.Equal(2, batcher[order[1]].Layer);
|
||||
Assert.Equal(10, batcher[order[2]].Layer); // ...затем чанк 1 — стабильно
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ChunkedSubmit_GrowsMainArrays_WhenNeeded()
|
||||
{
|
||||
var batcher = new SpriteBatcher(initialCapacity: 2);
|
||||
batcher.BeginChunks([10]);
|
||||
|
||||
var writer = batcher.GetChunkWriter(0);
|
||||
for (byte i = 0; i < 10; i++)
|
||||
{
|
||||
writer.Add(Instance(i), i);
|
||||
}
|
||||
|
||||
batcher.EndChunk(0, in writer);
|
||||
|
||||
Assert.Equal(10, batcher.CommitChunks());
|
||||
Assert.Equal(10, batcher.Count);
|
||||
Assert.Equal(0, batcher[batcher.Sort()[0]].Layer);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Clear_ResetsCount_KeepsWorking()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user