Skip to content

Commit 8d0afde

Browse files
[Rendering] Fixes to rendering clashing with passes;
1 parent a48e096 commit 8d0afde

File tree

13 files changed

+224
-48
lines changed

13 files changed

+224
-48
lines changed

Engine/Staple.Core/Rendering/Mesh/Mesh+Internal.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,8 @@ internal Mesh(bool readable, bool writable)
472472
{
473473
isReadable = readable;
474474
isWritable = writable;
475+
476+
ResourceManager.instance.userCreatedMeshes.Add(new(this));
475477
}
476478

477479
/// <summary>
@@ -868,8 +870,6 @@ void Copy<T>(T source, ref int index) where T: unmanaged
868870
/// <returns>Whether it was set active</returns>
869871
internal bool SetActive(ref RenderState state, int submeshIndex = 0)
870872
{
871-
UploadMeshData();
872-
873873
if(vertexBuffer == null || indexBuffer == null)
874874
{
875875
return false;

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ public static object Create(string guid)
10011001

10021002
public Mesh()
10031003
{
1004+
ResourceManager.instance.userCreatedMeshes.Add(new(this));
10041005
}
10051006

10061007
/// <summary>
@@ -1125,7 +1126,7 @@ public void SetMeshData<T>(Span<T> meshData, VertexLayout vertexLayout) where T
11251126
/// <summary>
11261127
/// Uploads the mesh data to the GPU
11271128
/// </summary>
1128-
public void UploadMeshData()
1129+
internal void UploadMeshData()
11291130
{
11301131
if (changed == false &&
11311132
(vertexBuffer?.Disposed ?? true) == false &&

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,6 @@ public static void RenderMesh(Mesh mesh, Vector3 position, Quaternion rotation,
6969
return;
7070
}
7171

72-
mesh.UploadMeshData();
73-
7472
var matrix = Matrix4x4.TRS(position, scale, rotation);
7573

7674
var renderState = new RenderState()
@@ -144,8 +142,6 @@ public void Preprocess(Span<(Entity, Transform, IComponent)> entities, Camera ac
144142
continue;
145143
}
146144

147-
renderer.mesh.UploadMeshData();
148-
149145
if(transform.ChangedThisFrame || renderer.localBounds.size == Vector3.Zero)
150146
{
151147
var localSize = Vector3.Abs(renderer.mesh.bounds.size.Transformed(transform.LocalRotation));

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

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,35 @@ public override void Destroy()
2929
{
3030
base.Destroy();
3131

32-
if (buffer != nint.Zero)
32+
void Finish()
3333
{
34-
SDL.SDL_ReleaseGPUBuffer(device, buffer);
34+
SDL.SDL_WaitForGPUIdle(device);
3535

36-
buffer = nint.Zero;
36+
if (buffer != nint.Zero)
37+
{
38+
SDL.SDL_ReleaseGPUBuffer(device, buffer);
39+
40+
buffer = nint.Zero;
41+
}
42+
43+
if (transferBuffer != nint.Zero)
44+
{
45+
SDL.SDL_ReleaseGPUTransferBuffer(device, transferBuffer);
46+
47+
transferBuffer = nint.Zero;
48+
}
3749
}
3850

39-
if (transferBuffer != nint.Zero)
51+
if (backend.CanUpdateResources == false)
4052
{
41-
SDL.SDL_ReleaseGPUTransferBuffer(device, transferBuffer);
53+
SDLGPURendererBackend.ReportResourceUnavailability();
4254

43-
transferBuffer = nint.Zero;
55+
backend.QueueRenderUpdate(Finish);
56+
57+
return;
4458
}
59+
60+
Finish();
4561
}
4662

4763
public void ResizeIfNeeded(int lengthInBytes)
@@ -51,6 +67,13 @@ public void ResizeIfNeeded(int lengthInBytes)
5167
return;
5268
}
5369

70+
if (backend.CanUpdateResources == false)
71+
{
72+
SDLGPURendererBackend.ReportResourceUnavailability();
73+
74+
return;
75+
}
76+
5477
if (buffer != nint.Zero)
5578
{
5679
SDL.SDL_WaitForGPUIdle(device);
@@ -126,6 +149,13 @@ public override void Update(Span<ushort> data)
126149
return;
127150
}
128151

152+
if (backend.CanUpdateResources == false)
153+
{
154+
SDLGPURendererBackend.ReportResourceUnavailability();
155+
156+
return;
157+
}
158+
129159
var byteSize = data.Length * size;
130160

131161
ResizeIfNeeded(data.Length * byteSize);
@@ -182,6 +212,13 @@ public override void Update(Span<uint> data)
182212
return;
183213
}
184214

215+
if (backend.CanUpdateResources == false)
216+
{
217+
SDLGPURendererBackend.ReportResourceUnavailability();
218+
219+
return;
220+
}
221+
185222
var byteSize = data.Length * size;
186223

187224
ResizeIfNeeded(byteSize);

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace Staple.Internal;
66

7-
internal class SDLGPURenderPass(nint commandBuffer, nint renderPass, Matrix4x4 view, Matrix4x4 projection) : IRenderPass
7+
internal class SDLGPURenderPass(nint commandBuffer, nint renderPass, Matrix4x4 view, Matrix4x4 projection, SDLGPURendererBackend backend) : IRenderPass
88
{
99
public struct StapleRenderData
1010
{
@@ -18,24 +18,20 @@ public struct StapleRenderData
1818

1919
public readonly nint commandBuffer = commandBuffer;
2020

21+
public readonly SDLGPURendererBackend backend = backend;
22+
2123
public StapleRenderData renderData = new()
2224
{
2325
projection = projection,
2426
view = view,
2527
time = Time.time,
2628
};
2729

28-
private nint lastGraphicsPipeline;
2930
private bool appliedUniforms;
3031

3132
public void BindPipeline(nint pipeline)
3233
{
33-
//if (pipeline != lastGraphicsPipeline)
34-
{
35-
lastGraphicsPipeline = pipeline;
36-
37-
SDL.SDL_BindGPUGraphicsPipeline(renderPass, pipeline);
38-
}
34+
SDL.SDL_BindGPUGraphicsPipeline(renderPass, pipeline);
3935
}
4036

4137
public void ApplyBuiltinUniforms(in Matrix4x4 world)
@@ -68,5 +64,7 @@ public void Finish()
6864
SDL.SDL_EndGPURenderPass(renderPass);
6965

7066
renderPass = nint.Zero;
67+
68+
backend.PopRenderPassReference();
7169
}
7270
}

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

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
using System.Collections.Generic;
44
using System.Numerics;
55
using System.Text;
6+
using System.Threading;
67

78
namespace Staple.Internal;
89

910
internal class SDLGPURendererBackend : IRendererBackend
1011
{
12+
private int renderPassReferences;
13+
private readonly Lock renderPassReferenceLock = new();
14+
1115
private nint device;
1216
private SDL3RenderWindow window;
1317
private readonly Dictionary<int, nint> graphicsPipelines = [];
@@ -21,6 +25,19 @@ internal class SDLGPURendererBackend : IRendererBackend
2125
private int swapchainWidth;
2226
private int swapchainHeight;
2327

28+
private readonly List<Action> pendingResourceUpdates = [];
29+
30+
public bool CanUpdateResources
31+
{
32+
get
33+
{
34+
lock(renderPassReferenceLock)
35+
{
36+
return renderPassReferences == 0;
37+
}
38+
}
39+
}
40+
2441
public bool TryGetCommandBuffer(out nint buffer)
2542
{
2643
buffer = commandBuffer;
@@ -282,6 +299,18 @@ public void BeginFrame()
282299

283300
public void EndFrame()
284301
{
302+
lock(renderPassReferenceLock)
303+
{
304+
while(pendingResourceUpdates.Count > 0)
305+
{
306+
var first = pendingResourceUpdates[0];
307+
308+
pendingResourceUpdates.RemoveAt(0);
309+
310+
first?.Invoke();
311+
}
312+
}
313+
285314
if(commandBuffer != nint.Zero)
286315
{
287316
SDL.SDL_SubmitGPUCommandBuffer(commandBuffer);
@@ -307,9 +336,58 @@ private void UpdateDepthTextureIfNeeded()
307336
depthTexture = CreateEmptyTexture(swapchainWidth, swapchainHeight, DepthStencilFormat.Value, TextureFlags.DepthStencilTarget);
308337
}
309338

339+
public void PushRenderPassReference()
340+
{
341+
lock(renderPassReferenceLock)
342+
{
343+
renderPassReferences++;
344+
}
345+
}
346+
347+
public void PopRenderPassReference()
348+
{
349+
lock (renderPassReferenceLock)
350+
{
351+
renderPassReferences--;
352+
353+
if (renderPassReferences < 0)
354+
{
355+
Log.Error($"[Rendering] Render pass references reached a negative value! Are you ensuring you're pushing the same amount as you pop?");
356+
357+
renderPassReferences = 0;
358+
}
359+
}
360+
}
361+
362+
public void QueueRenderUpdate(Action update)
363+
{
364+
lock(renderPassReferenceLock)
365+
{
366+
pendingResourceUpdates.Add(update);
367+
}
368+
}
369+
370+
public static void ReportResourceUnavailability()
371+
{
372+
Log.Error($"Unable to update a resource. Resources can only be updated outside of a rendering phase!\n{Environment.StackTrace}");
373+
}
374+
310375
public IRenderPass BeginRenderPass(RenderTarget target, CameraClearMode clear, Color clearColor, Vector4 viewport,
311376
Matrix4x4 view, Matrix4x4 projection)
312377
{
378+
if(CanUpdateResources)
379+
{
380+
foreach(var pair in ResourceManager.instance.userCreatedMeshes)
381+
{
382+
if(pair.TryGetTarget(out var mesh) == false)
383+
{
384+
continue;
385+
}
386+
387+
mesh.UploadMeshData();
388+
}
389+
}
390+
313391
if (commandBuffer == nint.Zero)
314392
{
315393
return null;
@@ -413,7 +491,9 @@ public IRenderPass BeginRenderPass(RenderTarget target, CameraClearMode clear, C
413491

414492
SDL.SDL_SetGPUViewport(renderPass, in viewportData);
415493

416-
return new SDLGPURenderPass(commandBuffer, renderPass, view, projection);
494+
PushRenderPassReference();
495+
496+
return new SDLGPURenderPass(commandBuffer, renderPass, view, projection, this);
417497
}
418498

419499
public VertexBuffer CreateVertexBuffer(Span<byte> data, VertexLayout layout, RenderBufferFlags flags)

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

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -622,21 +622,35 @@ public void Destroy()
622622

623623
Disposed = true;
624624

625-
SDL.SDL_WaitForGPUIdle(device);
626-
627-
if (texture != nint.Zero)
625+
void Finish()
628626
{
629-
SDL.SDL_ReleaseGPUTexture(device, texture);
627+
SDL.SDL_WaitForGPUIdle(device);
628+
629+
if (texture != nint.Zero)
630+
{
631+
SDL.SDL_ReleaseGPUTexture(device, texture);
632+
633+
texture = nint.Zero;
634+
}
635+
636+
if (transferBuffer != nint.Zero)
637+
{
638+
SDL.SDL_ReleaseGPUTransferBuffer(device, transferBuffer);
630639

631-
texture = nint.Zero;
640+
transferBuffer = nint.Zero;
641+
}
632642
}
633643

634-
if(transferBuffer != nint.Zero)
644+
if (backend.CanUpdateResources == false)
635645
{
636-
SDL.SDL_ReleaseGPUTransferBuffer(device, transferBuffer);
646+
SDLGPURendererBackend.ReportResourceUnavailability();
637647

638-
transferBuffer = nint.Zero;
648+
backend.QueueRenderUpdate(Finish);
649+
650+
return;
639651
}
652+
653+
Finish();
640654
}
641655

642656
public void Update(Span<byte> data)
@@ -646,6 +660,13 @@ public void Update(Span<byte> data)
646660
return;
647661
}
648662

663+
if (backend.CanUpdateResources == false)
664+
{
665+
SDLGPURendererBackend.ReportResourceUnavailability();
666+
667+
return;
668+
}
669+
649670
if (backend.TryGetCommandBuffer(out var command) == false)
650671
{
651672
return;

0 commit comments

Comments
 (0)