Skip to content

Commit b36e465

Browse files
[Rendering] Reuse transfer buffers;
1 parent a3becc3 commit b36e465

File tree

8 files changed

+78
-84
lines changed

8 files changed

+78
-84
lines changed

Engine/Staple.Core/Rendering/Mesh/MeshRenderSystem.cs

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Numerics;
4-
using System.Reflection.Metadata;
5-
using System.Runtime.InteropServices;
64

75
namespace Staple.Internal;
86

@@ -27,11 +25,12 @@ private class InstanceData
2725
{
2826
public ExpandableContainer<InstanceInfo> instanceInfos = new();
2927
public Matrix4x4[] transformMatrices = [];
30-
public VertexBuffer instanceBuffer;
3128
}
3229

3330
private readonly Dictionary<int, InstanceData> instanceCache = [];
3431

32+
private readonly Dictionary<int, VertexBuffer> instanceBuffers = [];
33+
3534
private readonly Lazy<VertexLayout> instanceLayout = new(() =>
3635
{
3736
return VertexLayoutBuilder.CreateNew()
@@ -60,6 +59,27 @@ public void Prepare()
6059
}
6160
#endregion
6261

62+
private VertexBuffer GetInstanceBuffer(int count)
63+
{
64+
if (instanceBuffers.TryGetValue(count, out var buffer) && buffer.Disposed == false)
65+
{
66+
return buffer;
67+
}
68+
69+
buffer = VertexBuffer.Create(new Matrix4x4[count], instanceLayout.Value, RenderBufferFlags.GraphicsRead);
70+
71+
if((buffer?.Disposed ?? true))
72+
{
73+
instanceBuffers.Remove(count);
74+
75+
return null;
76+
}
77+
78+
instanceBuffers.AddOrSetKey(count, buffer);
79+
80+
return buffer;
81+
}
82+
6383
/// <summary>
6484
/// Renders a mesh
6585
/// </summary>
@@ -309,20 +329,20 @@ public void Submit()
309329
contents.transformMatrices[i] = contents.instanceInfos.Contents[i].transform.Matrix;
310330
}
311331

312-
if(contents.instanceBuffer == null)
313-
{
314-
contents.instanceBuffer = VertexBuffer.Create(contents.transformMatrices, instanceLayout.Value, RenderBufferFlags.GraphicsRead);
315-
}
316-
else
332+
var buffer = GetInstanceBuffer(contents.transformMatrices.Length);
333+
334+
if(buffer == null)
317335
{
318-
contents.instanceBuffer.Update(contents.transformMatrices);
336+
continue;
319337
}
320338

321-
if (contents.instanceBuffer != null)
339+
buffer.Update(contents.transformMatrices);
340+
341+
if (buffer != null)
322342
{
323343
renderState.instanceCount = contents.transformMatrices.Length;
324344

325-
renderState.ApplyStorageBufferIfNeeded("StapleInstancingTransforms", contents.instanceBuffer);
345+
renderState.ApplyStorageBufferIfNeeded("StapleInstancingTransforms", buffer);
326346

327347
RenderSystem.Submit(renderState, renderData.mesh.SubmeshTriangleCount(contents.instanceInfos.Contents[0].submeshIndex),
328348
contents.instanceInfos.Length);

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,7 @@ public void Update(IRendererBackend rendererBackend)
1919
return;
2020
}
2121

22-
if (resource.transferBuffer != nint.Zero)
23-
{
24-
SDL.ReleaseGPUTransferBuffer(backend.device, resource.transferBuffer);
25-
26-
resource.transferBuffer = nint.Zero;
27-
}
28-
29-
var info = new SDL.GPUTransferBufferCreateInfo()
30-
{
31-
Size = (uint)resource.length,
32-
Usage = SDL.GPUTransferBufferUsage.Download,
33-
};
34-
35-
resource.transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in info);
22+
resource.transferBuffer = backend.GetTransferBuffer(true, resource.length);
3623

3724
if (resource.transferBuffer == nint.Zero)
3825
{

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public void Update(IRendererBackend rendererBackend)
2424
if (buffer.buffer != nint.Zero)
2525
{
2626
SDL.ReleaseGPUBuffer(backend.device, buffer.buffer);
27-
SDL.ReleaseGPUTransferBuffer(backend.device, buffer.transferBuffer);
2827

2928
buffer.transferBuffer = nint.Zero;
3029
buffer.buffer = nint.Zero;
@@ -60,13 +59,7 @@ public void Update(IRendererBackend rendererBackend)
6059
return;
6160
}
6261

63-
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
64-
{
65-
Size = (uint)data.Length,
66-
Usage = SDL.GPUTransferBufferUsage.Upload,
67-
};
68-
69-
buffer.transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in transferInfo);
62+
buffer.transferBuffer = backend.GetTransferBuffer(false, data.Length);
7063

7164
if (buffer.transferBuffer == nint.Zero)
7265
{
@@ -93,7 +86,7 @@ public void Update(IRendererBackend rendererBackend)
9386
return;
9487
}
9588

96-
var mapData = SDL.MapGPUTransferBuffer(backend.device, buffer.transferBuffer, false);
89+
var mapData = SDL.MapGPUTransferBuffer(backend.device, buffer.transferBuffer, true);
9790

9891
unsafe
9992
{

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

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,10 @@ public void Update(IRendererBackend rendererBackend)
2121
{
2222
if(resource.transferBuffer != nint.Zero)
2323
{
24-
SDL.ReleaseGPUTransferBuffer(backend.device, resource.transferBuffer);
25-
2624
resource.transferBuffer = nint.Zero;
2725
}
2826

29-
var info = new SDL.GPUTransferBufferCreateInfo()
30-
{
31-
Size = (uint)data.Length,
32-
Usage = SDL.GPUTransferBufferUsage.Upload,
33-
};
34-
35-
resource.transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in info);
27+
resource.transferBuffer = backend.GetTransferBuffer(false, data.Length);
3628

3729
if (resource.transferBuffer == nint.Zero)
3830
{
@@ -55,7 +47,7 @@ public void Update(IRendererBackend rendererBackend)
5547
return;
5648
}
5749

58-
var mapData = SDL.MapGPUTransferBuffer(backend.device, resource.transferBuffer, false);
50+
var mapData = SDL.MapGPUTransferBuffer(backend.device, resource.transferBuffer, true);
5951

6052
unsafe
6153
{

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public void Update(IRendererBackend rendererBackend)
2424
if (buffer.buffer != nint.Zero)
2525
{
2626
SDL.ReleaseGPUBuffer(backend.device, buffer.buffer);
27-
SDL.ReleaseGPUTransferBuffer(backend.device, buffer.transferBuffer);
2827

2928
buffer.transferBuffer = nint.Zero;
3029
buffer.buffer = nint.Zero;
@@ -60,13 +59,7 @@ public void Update(IRendererBackend rendererBackend)
6059
return;
6160
}
6261

63-
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
64-
{
65-
Size = (uint)data.Length,
66-
Usage = SDL.GPUTransferBufferUsage.Upload,
67-
};
68-
69-
buffer.transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in transferInfo);
62+
buffer.transferBuffer = backend.GetTransferBuffer(false, data.Length);
7063

7164
if (buffer.transferBuffer == nint.Zero)
7265
{
@@ -93,7 +86,7 @@ public void Update(IRendererBackend rendererBackend)
9386
return;
9487
}
9588

96-
var mapData = SDL.MapGPUTransferBuffer(backend.device, buffer.transferBuffer, false);
89+
var mapData = SDL.MapGPUTransferBuffer(backend.device, buffer.transferBuffer, true);
9790

9891
unsafe
9992
{

Engine/Staple.Core/Rendering/RenderSystem/Backend/Impls/SDLGPU/SDLGPURendererBackend+Buffers.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,31 @@ namespace Staple.Internal;
55

66
internal partial class SDLGPURendererBackend
77
{
8+
internal nint GetTransferBuffer(bool download, int length)
9+
{
10+
var key = new TransferBufferCacheKey(download, length);
11+
12+
if(cachedTransferBuffers.TryGetValue(key, out var buffer))
13+
{
14+
return buffer;
15+
}
16+
17+
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
18+
{
19+
Size = (uint)length,
20+
Usage = download ? SDL.GPUTransferBufferUsage.Download : SDL.GPUTransferBufferUsage.Upload,
21+
};
22+
23+
buffer = SDL.CreateGPUTransferBuffer(device, in transferInfo);
24+
25+
if (buffer != nint.Zero)
26+
{
27+
cachedTransferBuffers.Add(key, buffer);
28+
}
29+
30+
return buffer;
31+
}
32+
833
internal void ReleaseBufferResource(BufferResource resource)
934
{
1035
if ((resource?.used ?? false) == false)
@@ -14,8 +39,6 @@ internal void ReleaseBufferResource(BufferResource resource)
1439

1540
if (resource.transferBuffer != nint.Zero)
1641
{
17-
SDL.ReleaseGPUTransferBuffer(device, resource.transferBuffer);
18-
1942
resource.transferBuffer = nint.Zero;
2043
}
2144

Engine/Staple.Core/Rendering/RenderSystem/Backend/Impls/SDLGPU/SDLGPURendererBackend+Textures.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ internal void ReleaseTextureResource(TextureResource resource)
2525

2626
if (resource.transferBuffer != nint.Zero)
2727
{
28-
SDL.ReleaseGPUTransferBuffer(device, resource.transferBuffer);
29-
3028
resource.transferBuffer = nint.Zero;
3129
}
3230

Engine/Staple.Core/Rendering/RenderSystem/Backend/Impls/SDLGPU/SDLGPURendererBackend.cs

Lines changed: 15 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,17 @@ internal class ViewData
8383
public StapleFragmentRenderData fragmentData;
8484
}
8585

86+
private readonly struct TransferBufferCacheKey(bool download, int length)
87+
{
88+
public readonly bool download = download;
89+
public readonly int length = length;
90+
91+
public override int GetHashCode()
92+
{
93+
return HashCode.Combine(download, length);
94+
}
95+
}
96+
8697
internal class TransientEntry
8798
{
8899
public readonly List<byte> vertices = [];
@@ -158,13 +169,7 @@ public void CreateBuffers()
158169
return;
159170
}
160171

161-
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
162-
{
163-
Size = (uint)vertices.Count,
164-
Usage = SDL.GPUTransferBufferUsage.Upload,
165-
};
166-
167-
var transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in transferInfo);
172+
var transferBuffer = backend.GetTransferBuffer(false, vertices.Count);
168173

169174
if (transferBuffer == nint.Zero)
170175
{
@@ -218,8 +223,6 @@ public void CreateBuffers()
218223
};
219224

220225
SDL.UploadToGPUBuffer(backend.copyPass, in location, in region, false);
221-
222-
SDL.ReleaseGPUTransferBuffer(backend.device, transferBuffer);
223226
}
224227

225228
if(indices.Count > 0)
@@ -239,13 +242,7 @@ public void CreateBuffers()
239242
return;
240243
}
241244

242-
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
243-
{
244-
Size = (uint)(indices.Count * sizeof(ushort)),
245-
Usage = SDL.GPUTransferBufferUsage.Upload,
246-
};
247-
248-
var transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in transferInfo);
245+
var transferBuffer = backend.GetTransferBuffer(false, indices.Count * sizeof(ushort));
249246

250247
if (transferBuffer == nint.Zero)
251248
{
@@ -299,8 +296,6 @@ public void CreateBuffers()
299296
};
300297

301298
SDL.UploadToGPUBuffer(backend.copyPass, in location, in region, false);
302-
303-
SDL.ReleaseGPUTransferBuffer(backend.device, transferBuffer);
304299
}
305300

306301
if (uintIndices.Count > 0)
@@ -320,13 +315,7 @@ public void CreateBuffers()
320315
return;
321316
}
322317

323-
var transferInfo = new SDL.GPUTransferBufferCreateInfo()
324-
{
325-
Size = (uint)(uintIndices.Count * sizeof(uint)),
326-
Usage = SDL.GPUTransferBufferUsage.Upload,
327-
};
328-
329-
var transferBuffer = SDL.CreateGPUTransferBuffer(backend.device, in transferInfo);
318+
var transferBuffer = backend.GetTransferBuffer(false, uintIndices.Count * sizeof(uint));
330319

331320
if (transferBuffer == nint.Zero)
332321
{
@@ -386,8 +375,6 @@ public void CreateBuffers()
386375
};
387376

388377
SDL.UploadToGPUBuffer(backend.copyPass, in location, in region, false);
389-
390-
SDL.ReleaseGPUTransferBuffer(backend.device, transferBuffer);
391378
}
392379
}
393380
}
@@ -458,6 +445,7 @@ public void Clear()
458445
private readonly Dictionary<VertexLayout, TransientEntry> transientBuffers = [];
459446
private readonly TextureResource[] textures = new TextureResource[ushort.MaxValue - 1];
460447
private readonly List<SDLGPUShaderProgram> shaders = [];
448+
private readonly Dictionary<TransferBufferCacheKey, nint> cachedTransferBuffers = [];
461449
private RenderTarget currentRenderTarget;
462450

463451
private bool iteratingCommands = false;

0 commit comments

Comments
 (0)