Skip to content

Commit 88f22b6

Browse files
[Rendering] Performance improvements;
[Utilities] Add GlobalAllocator; [Utilities] Refactor Freeform Allocator into Managed and Unmanaged versions;
1 parent 2117997 commit 88f22b6

14 files changed

Lines changed: 518 additions & 205 deletions

Engine/Staple.Core.Tests/FreeformAllocatorTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ internal class FreeformAllocatorTests
88
[Test]
99
public void TestAllocate()
1010
{
11-
var allocator = new FreeformAllocator<Vector2>();
11+
var allocator = new UnmanagedFreeformAllocator<Vector2>();
1212

1313
var entry = allocator.Allocate(20);
1414

@@ -34,7 +34,7 @@ public void TestAllocate()
3434
[Test]
3535
public void TestFree()
3636
{
37-
var allocator = new FreeformAllocator<Vector2>();
37+
var allocator = new UnmanagedFreeformAllocator<Vector2>();
3838

3939
var entry = allocator.Allocate(20);
4040

@@ -61,7 +61,7 @@ public void TestFree()
6161
[Test]
6262
public void TestCompact()
6363
{
64-
var allocator = new FreeformAllocator<Vector2>();
64+
var allocator = new UnmanagedFreeformAllocator<Vector2>();
6565

6666
var entry = allocator.Allocate(20);
6767

Engine/Staple.Core/Entities/Transform.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Numerics;
33
using System.Runtime.CompilerServices;
4+
using System.Runtime.InteropServices;
45

56
namespace Staple;
67

@@ -459,7 +460,14 @@ private void BumpVersion()
459460
{
460461
version++;
461462

462-
for (var i = 0; i < Children.Length; i++)
463+
if(Children.Length == 0)
464+
{
465+
return;
466+
}
467+
468+
var length = Children.Length;
469+
470+
for (var i = 0; i < length; i++)
463471
{
464472
Children[i].BumpVersion();
465473
}

Engine/Staple.Core/Rendering/RenderSystem/Backend/BufferAttributeContainer.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,26 @@ internal enum BufferSlot
3232

3333
public class Entries
3434
{
35-
public FreeformAllocator<Vector3>.Entry positionEntry;
36-
public FreeformAllocator<Vector3>.Entry normalEntry;
37-
public FreeformAllocator<Vector3>.Entry tangentEntry;
38-
public FreeformAllocator<Vector3>.Entry bitangentEntry;
39-
public FreeformAllocator<Vector4>.Entry blendIndicesEntry;
40-
public FreeformAllocator<Vector4>.Entry blendWeightsEntry;
41-
public FreeformAllocator<Color>.Entry color0Entry;
42-
public FreeformAllocator<Color>.Entry color1Entry;
43-
public FreeformAllocator<Color>.Entry color2Entry;
44-
public FreeformAllocator<Color>.Entry color3Entry;
45-
public FreeformAllocator<Vector2>.Entry texCoord0Entry;
46-
public FreeformAllocator<Vector2>.Entry texCoord1Entry;
47-
public FreeformAllocator<Vector2>.Entry texCoord2Entry;
48-
public FreeformAllocator<Vector2>.Entry texCoord3Entry;
49-
public FreeformAllocator<Vector2>.Entry texCoord4Entry;
50-
public FreeformAllocator<Vector2>.Entry texCoord5Entry;
51-
public FreeformAllocator<Vector2>.Entry texCoord6Entry;
52-
public FreeformAllocator<Vector2>.Entry texCoord7Entry;
53-
54-
public FreeformAllocator<uint>.Entry indicesEntry;
35+
public UnmanagedFreeformAllocator<Vector3>.Entry positionEntry;
36+
public UnmanagedFreeformAllocator<Vector3>.Entry normalEntry;
37+
public UnmanagedFreeformAllocator<Vector3>.Entry tangentEntry;
38+
public UnmanagedFreeformAllocator<Vector3>.Entry bitangentEntry;
39+
public UnmanagedFreeformAllocator<Vector4>.Entry blendIndicesEntry;
40+
public UnmanagedFreeformAllocator<Vector4>.Entry blendWeightsEntry;
41+
public UnmanagedFreeformAllocator<Color>.Entry color0Entry;
42+
public UnmanagedFreeformAllocator<Color>.Entry color1Entry;
43+
public UnmanagedFreeformAllocator<Color>.Entry color2Entry;
44+
public UnmanagedFreeformAllocator<Color>.Entry color3Entry;
45+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord0Entry;
46+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord1Entry;
47+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord2Entry;
48+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord3Entry;
49+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord4Entry;
50+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord5Entry;
51+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord6Entry;
52+
public UnmanagedFreeformAllocator<Vector2>.Entry texCoord7Entry;
53+
54+
public UnmanagedFreeformAllocator<uint>.Entry indicesEntry;
5555
}
5656

5757
public readonly BufferAttributeSource<Vector3, VertexBuffer> Position = new(VertexAttribute.Position, BufferSlot.Position);

Engine/Staple.Core/Rendering/RenderSystem/Backend/BufferAttributeSource.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace Staple.Internal;
66

77
internal class BufferAttributeSource<T, BufferType>(VertexAttribute attribute, BufferAttributeContainer.BufferSlot slot, T? defaultValue = null) where T: unmanaged
88
{
9-
public readonly FreeformAllocator<T> allocator = new();
9+
public readonly UnmanagedFreeformAllocator<T> allocator = new();
1010

1111
public readonly VertexAttribute attribute = attribute;
1212

@@ -24,7 +24,7 @@ internal class BufferAttributeSource<T, BufferType>(VertexAttribute attribute, B
2424

2525
public bool Changed { get; set; }
2626

27-
public FreeformAllocator<T>.Entry Allocate(int elementCount)
27+
public UnmanagedFreeformAllocator<T>.Entry Allocate(int elementCount)
2828
{
2929
Changed = true;
3030

@@ -47,7 +47,7 @@ public FreeformAllocator<T>.Entry Allocate(int elementCount)
4747
return entry;
4848
}
4949

50-
public void Free(FreeformAllocator<T>.Entry entry)
50+
public void Free(UnmanagedFreeformAllocator<T>.Entry entry)
5151
{
5252
Changed = true;
5353

Engine/Staple.Core/Rendering/RenderSystem/Backend/Impls/SDLGPU/Commands/SDLGPURenderCommand.cs

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SDL3;
2+
using Staple.Utilities;
23

34
namespace Staple.Internal;
45

@@ -26,6 +27,9 @@ public void Update(IRendererBackend rendererBackend)
2627
SDLGPURendererBackend.BufferResource vertexBuffer = null;
2728
SDLGPURendererBackend.BufferResource indexBuffer = null;
2829

30+
using var vertexUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(vertexUniformData);
31+
using var fragmentUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(fragmentUniformData);
32+
2933
if ((staticMeshEntries == null &&
3034
(!backend.TryGetVertexBuffer(vertex.handle, out vertexBuffer) ||
3135
!backend.TryGetIndexBuffer(index.handle, out indexBuffer))) ||
@@ -36,6 +40,9 @@ public void Update(IRendererBackend rendererBackend)
3640
return;
3741
}
3842

43+
using var vertexSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(vertexSamplers);
44+
using var fragmentSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(fragmentSamplers);
45+
3946
if (staticMeshEntries != null)
4047
{
4148
for (var i = 0; i < vertexAttributes.Length; i++)
@@ -72,48 +79,6 @@ public void Update(IRendererBackend rendererBackend)
7279
SDL.BindGPUGraphicsPipeline(renderPass, pipeline);
7380
}
7481

75-
if (hasVertexStorageBuffers)
76-
{
77-
for (var i = 0; i < state.vertexStorageBuffers.Count; i++)
78-
{
79-
var binding = state.vertexStorageBuffers[i];
80-
81-
if (binding.buffer.Disposed ||
82-
binding.buffer is not SDLGPUVertexBuffer v ||
83-
!backend.TryGetVertexBuffer(v.handle, out var resource) ||
84-
!resource.used ||
85-
resource.buffer == nint.Zero)
86-
{
87-
return;
88-
}
89-
90-
SDLGPURendererBackend.singleBuffer[0] = resource.buffer;
91-
92-
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)binding.binding, SDLGPURendererBackend.singleBuffer, 1);
93-
}
94-
}
95-
96-
if (hasFragmentStorageBuffers)
97-
{
98-
for (var i = 0; i < state.fragmentStorageBuffers.Count; i++)
99-
{
100-
var binding = state.fragmentStorageBuffers[i];
101-
102-
if (binding.buffer.Disposed ||
103-
binding.buffer is not SDLGPUVertexBuffer v ||
104-
!backend.TryGetVertexBuffer(v.handle, out var resource) ||
105-
!resource.used ||
106-
resource.buffer == nint.Zero)
107-
{
108-
return;
109-
}
110-
111-
SDLGPURendererBackend.singleBuffer[0] = resource.buffer;
112-
113-
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)binding.binding, SDLGPURendererBackend.singleBuffer, 1);
114-
}
115-
}
116-
11782
if (staticMeshEntries == null)
11883
{
11984
vertexBinding[0].Buffer = vertexBuffer.buffer;
@@ -167,6 +132,66 @@ binding.buffer is not SDLGPUVertexBuffer v ||
167132
SDL.BindGPUFragmentSamplers(renderPass, 0, fragmentSamplers, (uint)fragmentSamplers.Length);
168133
}
169134

135+
if (hasVertexStorageBuffers)
136+
{
137+
var buffers = GlobalAllocator<nint>.Instance.Rent(state.vertexStorageBuffers.Count);
138+
var counter = 0;
139+
var firstBinding = -1;
140+
141+
foreach (var (binding, buffer) in state.vertexStorageBuffers)
142+
{
143+
if (buffer.Disposed ||
144+
buffer is not SDLGPUVertexBuffer v ||
145+
!backend.TryGetVertexBuffer(v.handle, out var resource) ||
146+
!resource.used ||
147+
resource.buffer == nint.Zero)
148+
{
149+
return;
150+
}
151+
152+
buffers[counter++] = resource.buffer;
153+
154+
if (firstBinding < 0)
155+
{
156+
firstBinding = binding;
157+
}
158+
}
159+
160+
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
161+
162+
GlobalAllocator<nint>.Instance.Return(buffers);
163+
}
164+
165+
if (hasFragmentStorageBuffers)
166+
{
167+
var buffers = GlobalAllocator<nint>.Instance.Rent(state.fragmentStorageBuffers.Count);
168+
var counter = 0;
169+
var firstBinding = -1;
170+
171+
foreach (var (binding, buffer) in state.fragmentStorageBuffers)
172+
{
173+
if (buffer.Disposed ||
174+
buffer is not SDLGPUVertexBuffer v ||
175+
!backend.TryGetVertexBuffer(v.handle, out var resource) ||
176+
!resource.used ||
177+
resource.buffer == nint.Zero)
178+
{
179+
return;
180+
}
181+
182+
buffers[counter++] = resource.buffer;
183+
184+
if (firstBinding < 0)
185+
{
186+
firstBinding = binding;
187+
}
188+
}
189+
190+
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
191+
192+
GlobalAllocator<nint>.Instance.Return(buffers);
193+
}
194+
170195
for (var i = 0; i < vertexUniformData.Length; i++)
171196
{
172197
var uniform = vertexUniformData[i];

0 commit comments

Comments
 (0)