Skip to content

Commit cd1eecb

Browse files
[Rendering] Use Frame Allocator for uniforms and texture sampler bindings;
1 parent d15a7f0 commit cd1eecb

File tree

7 files changed

+339
-187
lines changed

7 files changed

+339
-187
lines changed

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

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
namespace Staple.Internal;
55

66
internal class SDLGPURenderCommand(SDLGPURendererBackend backend, RenderState state, nint pipeline, Texture[] vertexTextures,
7-
Texture[] fragmentTextures, StapleShaderUniform[] vertexUniformData, StapleShaderUniform[] fragmentUniformData,
7+
Texture[] fragmentTextures, (int, int) vertexUniformData, (int, int) fragmentUniformData,
88
VertexAttribute[] vertexAttributes) : IRenderCommand
99
{
1010
private readonly RenderState state = state.Clone();
1111
private readonly Texture[] vertexTextures = (Texture[])vertexTextures?.Clone();
1212
private readonly Texture[] fragmentTextures = (Texture[])fragmentTextures?.Clone();
13+
private readonly SDLGPUVertexBuffer vertex = (SDLGPUVertexBuffer)state.vertexBuffer;
14+
private readonly SDLGPUIndexBuffer index = (SDLGPUIndexBuffer)state.indexBuffer;
15+
private readonly BufferAttributeContainer.Entries staticMeshEntries = state.staticMeshEntries;
1316

1417
internal static readonly SDL.GPUBufferBinding[] vertexBinding = new SDL.GPUBufferBinding[1];
1518

@@ -20,28 +23,27 @@ internal class SDLGPURenderCommand(SDLGPURendererBackend backend, RenderState st
2023

2124
public void Update()
2225
{
23-
var vertex = (SDLGPUVertexBuffer)state.vertexBuffer;
24-
var index = (SDLGPUIndexBuffer)state.indexBuffer;
25-
var staticMeshEntries = state.staticMeshEntries;
26-
2726
SDLGPURendererBackend.BufferResource vertexBuffer = null;
2827
SDLGPURendererBackend.BufferResource indexBuffer = null;
2928

30-
using var vertexUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(vertexUniformData);
31-
using var fragmentUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(fragmentUniformData);
32-
33-
if ((staticMeshEntries == null &&
34-
(!backend.TryGetVertexBuffer(vertex.handle, out vertexBuffer) ||
35-
!backend.TryGetIndexBuffer(index.handle, out indexBuffer))) ||
36-
(staticMeshEntries != null && SDLGPURendererBackend.staticMeshVertexBuffers[0] == nint.Zero) ||
37-
!backend.TryGetTextureSamplers(vertexTextures, fragmentTextures, state.shaderInstance,
38-
out var vertexSamplers, out var fragmentSamplers))
29+
if(staticMeshEntries == null)
30+
{
31+
if(!backend.TryGetVertexBuffer(vertex.handle, out vertexBuffer) ||
32+
!backend.TryGetIndexBuffer(index.handle, out indexBuffer))
33+
{
34+
return;
35+
}
36+
}
37+
else if(SDLGPURendererBackend.staticMeshVertexBuffers[0] == nint.Zero)
3938
{
4039
return;
4140
}
4241

43-
using var vertexSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(vertexSamplers);
44-
using var fragmentSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(fragmentSamplers);
42+
if (!backend.TryGetTextureSamplers(vertexTextures, fragmentTextures, state.shaderInstance, out var vertexSamplers,
43+
out var fragmentSamplers))
44+
{
45+
return;
46+
}
4547

4648
if (staticMeshEntries != null)
4749
{
@@ -122,22 +124,40 @@ public void Update()
122124
}
123125
}
124126

125-
if (vertexSamplers != null)
127+
if (vertexSamplers.IsEmpty == false)
126128
{
127-
SDL.BindGPUVertexSamplers(renderPass, 0, vertexSamplers, (uint)vertexSamplers.Length);
129+
unsafe
130+
{
131+
fixed(void *ptr = vertexSamplers)
132+
{
133+
SDL.BindGPUVertexSamplers(renderPass, 0, (nint)ptr, (uint)vertexSamplers.Length);
134+
}
135+
}
136+
128137
}
129138

130-
if (fragmentSamplers != null)
139+
if (fragmentSamplers.IsEmpty == false)
131140
{
132-
SDL.BindGPUFragmentSamplers(renderPass, 0, fragmentSamplers, (uint)fragmentSamplers.Length);
141+
unsafe
142+
{
143+
fixed (void* ptr = fragmentSamplers)
144+
{
145+
SDL.BindGPUFragmentSamplers(renderPass, 0, (nint)ptr, (uint)fragmentSamplers.Length);
146+
}
147+
}
133148
}
134149

135150
if (hasVertexStorageBuffers)
136151
{
137-
var buffers = GlobalAllocator<nint>.Instance.Rent(state.vertexStorageBuffers.Count);
152+
var buffers = backend.nintBufferStaging;
138153
var counter = 0;
139154
var firstBinding = -1;
140155

156+
if(state.vertexStorageBuffers.Count > buffers.Length)
157+
{
158+
return;
159+
}
160+
141161
foreach (var (binding, buffer) in state.vertexStorageBuffers)
142162
{
143163
if (buffer.Disposed ||
@@ -157,17 +177,20 @@ buffer is not SDLGPUVertexBuffer v ||
157177
}
158178
}
159179

160-
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
161-
162-
GlobalAllocator<nint>.Instance.Return(buffers);
180+
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)counter);
163181
}
164182

165183
if (hasFragmentStorageBuffers)
166184
{
167-
var buffers = GlobalAllocator<nint>.Instance.Rent(state.fragmentStorageBuffers.Count);
185+
var buffers = backend.nintBufferStaging;
168186
var counter = 0;
169187
var firstBinding = -1;
170188

189+
if (state.fragmentStorageBuffers.Count > buffers.Length)
190+
{
191+
return;
192+
}
193+
171194
foreach (var (binding, buffer) in state.fragmentStorageBuffers)
172195
{
173196
if (buffer.Disposed ||
@@ -187,14 +210,14 @@ buffer is not SDLGPUVertexBuffer v ||
187210
}
188211
}
189212

190-
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
191-
192-
GlobalAllocator<nint>.Instance.Return(buffers);
213+
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)counter);
193214
}
194215

195-
for (var i = 0; i < vertexUniformData.Length; i++)
216+
var vertexSpan = backend.shaderUniformFrameAllocator.GetSpan(vertexUniformData.Item1, vertexUniformData.Item2);
217+
218+
for (var i = 0; i < vertexSpan.Length; i++)
196219
{
197-
var uniform = vertexUniformData[i];
220+
var uniform = vertexSpan[i];
198221

199222
if(uniform.used == false)
200223
{
@@ -206,9 +229,11 @@ buffer is not SDLGPUVertexBuffer v ||
206229
SDL.PushGPUVertexUniformData(backend.commandBuffer, uniform.binding, target, (uint)uniform.size);
207230
}
208231

209-
for (var i = 0; i < fragmentUniformData.Length; i++)
232+
var fragmentSpan = backend.shaderUniformFrameAllocator.GetSpan(fragmentUniformData.Item1, fragmentUniformData.Item2);
233+
234+
for (var i = 0; i < fragmentSpan.Length; i++)
210235
{
211-
var uniform = fragmentUniformData[i];
236+
var uniform = fragmentSpan[i];
212237

213238
if (uniform.used == false)
214239
{

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

Lines changed: 42 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,24 @@
11
using SDL3;
2-
using Staple.Utilities;
32

43
namespace Staple.Internal;
54

65
internal class SDLGPURenderTransientCommand(SDLGPURendererBackend backend, RenderState state, nint pipeline, Texture[] vertexTextures,
7-
Texture[] fragmentTextures, StapleShaderUniform[] vertexUniformData, StapleShaderUniform[] fragmentUniformData,
8-
SDLGPURendererBackend.TransientEntry entry) : IRenderCommand
6+
Texture[] fragmentTextures, (int, int) vertexUniformData, (int, int) fragmentUniformData, SDLGPURendererBackend.TransientEntry entry) :
7+
IRenderCommand
98
{
109
private readonly RenderState state = state.Clone();
1110
private readonly Texture[] vertexTextures = (Texture[])vertexTextures?.Clone();
1211
private readonly Texture[] fragmentTextures = (Texture[])fragmentTextures?.Clone();
1312

1413
public void Update()
1514
{
16-
using var vertexUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(vertexUniformData);
17-
using var fragmentUniformHandle = new GlobalAllocator<StapleShaderUniform>.GlobalAllocatorHandle(fragmentUniformData);
18-
1915
if (entry.vertexBuffer == nint.Zero ||
2016
!backend.TryGetTextureSamplers(vertexTextures, fragmentTextures, state.shaderInstance,
2117
out var vertexSamplers, out var fragmentSamplers))
2218
{
2319
return;
2420
}
2521

26-
using var vertexSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(vertexSamplers);
27-
using var fragmentSamplerHandle = new GlobalAllocator<SDL.GPUTextureSamplerBinding>.GlobalAllocatorHandle(fragmentSamplers);
28-
2922
var hasVertexStorageBuffers = state.vertexStorageBuffers != null;
3023
var hasFragmentStorageBuffers = state.fragmentStorageBuffers != null;
3124

@@ -80,22 +73,40 @@ public void Update()
8073
SDL.BindGPUIndexBuffer(renderPass, in SDLGPURenderCommand.indexBinding, SDL.GPUIndexElementSize.IndexElementSize16Bit);
8174
}
8275

83-
if (vertexSamplers != null)
76+
if (vertexSamplers.IsEmpty == false)
8477
{
85-
SDL.BindGPUVertexSamplers(renderPass, 0, vertexSamplers, (uint)vertexSamplers.Length);
78+
unsafe
79+
{
80+
fixed (void* ptr = vertexSamplers)
81+
{
82+
SDL.BindGPUVertexSamplers(renderPass, 0, (nint)ptr, (uint)vertexSamplers.Length);
83+
}
84+
}
85+
8686
}
8787

88-
if (fragmentSamplers != null)
88+
if (fragmentSamplers.IsEmpty == false)
8989
{
90-
SDL.BindGPUFragmentSamplers(renderPass, 0, fragmentSamplers, (uint)fragmentSamplers.Length);
90+
unsafe
91+
{
92+
fixed (void* ptr = fragmentSamplers)
93+
{
94+
SDL.BindGPUFragmentSamplers(renderPass, 0, (nint)ptr, (uint)fragmentSamplers.Length);
95+
}
96+
}
9197
}
9298

9399
if (hasVertexStorageBuffers)
94100
{
95-
var buffers = GlobalAllocator<nint>.Instance.Rent(state.vertexStorageBuffers.Count);
101+
var buffers = backend.nintBufferStaging;
96102
var counter = 0;
97103
var firstBinding = -1;
98104

105+
if (state.vertexStorageBuffers.Count > buffers.Length)
106+
{
107+
return;
108+
}
109+
99110
foreach (var (binding, buffer) in state.vertexStorageBuffers)
100111
{
101112
if (buffer.Disposed ||
@@ -109,23 +120,26 @@ buffer is not SDLGPUVertexBuffer v ||
109120

110121
buffers[counter++] = resource.buffer;
111122

112-
if(firstBinding < 0)
123+
if (firstBinding < 0)
113124
{
114125
firstBinding = binding;
115126
}
116127
}
117128

118-
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
119-
120-
GlobalAllocator<nint>.Instance.Return(buffers);
129+
SDL.BindGPUVertexStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)counter);
121130
}
122131

123132
if (hasFragmentStorageBuffers)
124133
{
125-
var buffers = GlobalAllocator<nint>.Instance.Rent(state.fragmentStorageBuffers.Count);
134+
var buffers = backend.nintBufferStaging;
126135
var counter = 0;
127136
var firstBinding = -1;
128137

138+
if (state.fragmentStorageBuffers.Count > buffers.Length)
139+
{
140+
return;
141+
}
142+
129143
foreach (var (binding, buffer) in state.fragmentStorageBuffers)
130144
{
131145
if (buffer.Disposed ||
@@ -145,14 +159,14 @@ buffer is not SDLGPUVertexBuffer v ||
145159
}
146160
}
147161

148-
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)buffers.Length);
149-
150-
GlobalAllocator<nint>.Instance.Return(buffers);
162+
SDL.BindGPUFragmentStorageBuffers(renderPass, (uint)firstBinding, buffers, (uint)counter);
151163
}
152164

153-
for (var i = 0; i < vertexUniformData.Length; i++)
165+
var vertexSpan = backend.shaderUniformFrameAllocator.GetSpan(vertexUniformData.Item1, vertexUniformData.Item2);
166+
167+
for (var i = 0; i < vertexSpan.Length; i++)
154168
{
155-
var uniform = vertexUniformData[i];
169+
var uniform = vertexSpan[i];
156170

157171
if (uniform.used == false)
158172
{
@@ -164,9 +178,11 @@ buffer is not SDLGPUVertexBuffer v ||
164178
SDL.PushGPUVertexUniformData(backend.commandBuffer, uniform.binding, target, (uint)uniform.size);
165179
}
166180

167-
for (var i = 0; i < fragmentUniformData.Length; i++)
181+
var fragmentSpan = backend.shaderUniformFrameAllocator.GetSpan(fragmentUniformData.Item1, fragmentUniformData.Item2);
182+
183+
for (var i = 0; i < fragmentSpan.Length; i++)
168184
{
169-
var uniform = fragmentUniformData[i];
185+
var uniform = fragmentSpan[i];
170186

171187
if (uniform.used == false)
172188
{

0 commit comments

Comments
 (0)