refactor(lifetime): own render resource prefixes
Give terrain, sky, retained UI, portal preparation, and the update/render frame pair explicit single owners. Make shader, texture, text, bindless, and GL construction prefixes checked and retryable so partial failure cannot lose or replay resource ownership. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
fec0d94148
commit
c87b15303d
41 changed files with 3768 additions and 355 deletions
|
|
@ -1,5 +1,6 @@
|
|||
using Silk.NET.OpenGL;
|
||||
using AcDream.App.Rendering;
|
||||
using System.Runtime.ExceptionServices;
|
||||
|
||||
namespace AcDream.App.Rendering.Wb;
|
||||
|
||||
|
|
@ -96,41 +97,68 @@ internal static unsafe class TrackedGlResource
|
|||
|
||||
public static uint CreateBuffer(GL gl, string context)
|
||||
{
|
||||
GLHelpers.ThrowOnResourceError(gl, $"{context} (precondition)");
|
||||
uint name = gl.GenBuffer();
|
||||
try
|
||||
{
|
||||
if (name == 0)
|
||||
throw new InvalidOperationException($"OpenGL returned buffer name zero. Context: {context}");
|
||||
GLHelpers.ThrowOnResourceError(gl, context);
|
||||
GpuMemoryTracker.TrackResourceAllocation(GpuResourceType.Buffer);
|
||||
return name;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (name != 0)
|
||||
gl.DeleteBuffer(name);
|
||||
throw;
|
||||
}
|
||||
return CreateTrackedName(
|
||||
gl,
|
||||
"buffer",
|
||||
context,
|
||||
gl.GenBuffer,
|
||||
name => GlResourceCommand.DeleteBuffer(
|
||||
gl,
|
||||
name,
|
||||
$"rollback buffer {name} after failed {context}"),
|
||||
() => GpuMemoryTracker.TrackResourceAllocation(GpuResourceType.Buffer));
|
||||
}
|
||||
|
||||
public static uint CreateVertexArray(GL gl, string context)
|
||||
{
|
||||
GLHelpers.ThrowOnResourceError(gl, $"{context} (precondition)");
|
||||
uint name = gl.GenVertexArray();
|
||||
return CreateTrackedName(
|
||||
gl,
|
||||
"vertex-array",
|
||||
context,
|
||||
gl.GenVertexArray,
|
||||
name => GlResourceCommand.DeleteVertexArray(
|
||||
gl,
|
||||
name,
|
||||
$"rollback vertex array {name} after failed {context}"),
|
||||
() => GpuMemoryTracker.TrackResourceAllocation(GpuResourceType.VAO));
|
||||
}
|
||||
|
||||
private static uint CreateTrackedName(
|
||||
GL gl,
|
||||
string resourceName,
|
||||
string context,
|
||||
Func<uint> create,
|
||||
Action<uint> rollback,
|
||||
Action publishAccounting)
|
||||
{
|
||||
uint name = GlResourceCommand.CreateName(
|
||||
gl,
|
||||
$"{resourceName} for {context}",
|
||||
create,
|
||||
rollback);
|
||||
var cleanup = new ResourceCleanupGroup();
|
||||
cleanup.Add($"{resourceName} name {name}", () => rollback(name));
|
||||
try
|
||||
{
|
||||
if (name == 0)
|
||||
throw new InvalidOperationException($"OpenGL returned vertex-array name zero. Context: {context}");
|
||||
GLHelpers.ThrowOnResourceError(gl, context);
|
||||
GpuMemoryTracker.TrackResourceAllocation(GpuResourceType.VAO);
|
||||
publishAccounting();
|
||||
return name;
|
||||
}
|
||||
catch
|
||||
catch (Exception publicationFailure)
|
||||
{
|
||||
if (name != 0)
|
||||
gl.DeleteVertexArray(name);
|
||||
throw;
|
||||
try
|
||||
{
|
||||
cleanup.RetryCleanup();
|
||||
}
|
||||
catch (Exception cleanupFailure)
|
||||
{
|
||||
throw new GlResourceConstructionException(
|
||||
$"Publishing {resourceName} accounting failed and GL name {name} could not be released.",
|
||||
cleanup,
|
||||
[publicationFailure, cleanupFailure]);
|
||||
}
|
||||
|
||||
ExceptionDispatchInfo.Capture(publicationFailure).Throw();
|
||||
throw new InvalidOperationException("Unreachable resource-publication path.");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue