feat(render): Vulkan campaign V11 step 2 — delete the OpenGL backend
Vulkan is the sole, user-signed-off backend (V10 landed) and step 1 already removed ImGui/Studio/DevTools. This step deletes the GL rendering backend itself: every Gpu/Gl/** implementation, the Wb ManagedGL*/GLHelpers/GLSLShader/GLStateScope/RenderStateCache/ BindlessSupport family, Shader/ShaderProgramConstruction/SamplerCache, RenderBootstrap, and RenderFrameGlStateController. GameWindow.cs's Run()/CreateGraphics()/CreateBackbufferReader()/ OnLoad() collapse to their Vulkan-only arm; GameWindowGraphics loses its OpenGlGameWindowGraphics subclass. RuntimeOptions.RenderBackend and RenderBackendKind (incl. the Gl member of GpuBackendKind) are gone — there is nothing left to select between. The five world-draw dual-arm renderers (WbDrawDispatcher, EnvCellRenderer, TerrainModernRenderer, ParticleRenderer, SkyRenderer) and the composition roots (WorldRenderComposition, HostInputCameraComposition, LivePresentationComposition, FrameRootComposition) collapse to their RHI-only arm. GL-only diagnostic properties with a live external reader (DynamicBufferCount and friends) simplify to a documented `=> 0`/no-op rather than disappearing, since the reader is out of this commit's scope. A few GL-flavored mechanisms turned out to be backend-neutral once isolated: GlConstructionCleanupLedger is renamed ResourceConstructionCleanupLedger (exception-chain walking has nothing to do with GL), and GlfwNativePlatformProbe moved out of the otherwise GL-only GraphicalCapabilityRecord.cs into GraphicalWindowBackendSelection.cs before the rest of that file was deleted. Test files with no surviving subject are deleted outright (GraphicalCapabilityRequirementsTests, ShaderProgramConstructionTests, PortalDepthShaderParityTests, TextureCacheBindlessTests, TextRendererFailureSafetyTests, ClipFrameUploadTests, every Gpu/Gl/*Tests, GlTextureOwnershipTests, RenderFrameGlStateControllerTests); others get their dead GL-only members trimmed while their live assertions stay (ClipFrameLayoutTests' MeshClipSsboBinding check now reads GpuBindingModel.StorageClipRegions, the same binding index under its new backend-neutral name; GpuResourceRetirementTransactionTests drops its OpenGLGraphicsDevice-subclassing test double and the two GL queue tests it existed for). EnvCellRendererTests' construction helper now builds a real ObjectMeshManager via VulkanMeshPipelineDevice instead of passing null through a null-forgiving operator, since the RHI constructor never tolerated a null mesh manager and the old GL constructor (which did) is gone. Deferred to the next two steps, deliberately not touched here: the Silk.NET.OpenGL/.Extensions.ARB package references, IMeshPipelineDevice.Gl (WbMeshAdapter's GL? threading stays in place), Chorizite.Core's stale csproj comment (the package itself is still load-bearing — TextureFormat and friends are used well beyond the deleted ManagedGLUniformBuffer), and the CI/gate scripts. Build: `dotnet build AcDream.slnx -c Release` — 0 warnings, 0 errors. Tests: full-solution `dotnet test` green across every project (App.Tests 3937/3940 + 3 skips, Core.Tests 3296/3298 + 2 skips, all others 100%); the 2 App.Tests names that flake under full-suite parallel execution (#250-family, documented pre-existing) pass in isolation. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
b70b9832ff
commit
8a7a0837e1
121 changed files with 1243 additions and 19840 deletions
|
|
@ -1,8 +1,6 @@
|
|||
using AcDream.App.Rendering.Gpu;
|
||||
using AcDream.App.Rendering.Gpu.Gl;
|
||||
using AcDream.Core.Textures;
|
||||
using AcDream.Core.World;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
||||
|
|
@ -163,192 +161,6 @@ internal interface ICompositeTextureArrayBackend
|
|||
void Delete(CompositeTextureArrayResource resource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Narrow GL backend for composite arrays. Unlike ManagedGLTextureArray it
|
||||
/// deliberately has one mip level, no PBO, and one resident handle: those are
|
||||
/// the semantics of the standalone composite textures this pool replaces.
|
||||
/// </summary>
|
||||
internal sealed unsafe class GlCompositeTextureArrayBackend : ICompositeTextureArrayBackend
|
||||
{
|
||||
private readonly GL _gl;
|
||||
private readonly Wb.BindlessSupport _bindless;
|
||||
private readonly GlGpuDevice _device;
|
||||
|
||||
public GlCompositeTextureArrayBackend(GL gl, Wb.BindlessSupport bindless, GlGpuDevice device)
|
||||
{
|
||||
_gl = gl ?? throw new ArgumentNullException(nameof(gl));
|
||||
_bindless = bindless ?? throw new ArgumentNullException(nameof(bindless));
|
||||
_device = device ?? throw new ArgumentNullException(nameof(device));
|
||||
_gl.GetInteger(GetPName.MaxArrayTextureLayers, out int maximumLayers);
|
||||
MaximumArrayLayers = Math.Max(1, maximumLayers);
|
||||
}
|
||||
|
||||
public int MaximumArrayLayers { get; }
|
||||
|
||||
public CompositeTextureArrayResource Create(int width, int height, int capacity)
|
||||
{
|
||||
uint name = _gl.GenTexture();
|
||||
if (name == 0)
|
||||
throw new InvalidOperationException("OpenGL did not create a composite texture array.");
|
||||
|
||||
bool resident = false;
|
||||
ulong handle = 0;
|
||||
long bytes = 0;
|
||||
bool tracked = false;
|
||||
try
|
||||
{
|
||||
// Composite creation/upload runs in the render thread's pre-draw
|
||||
// preparation phase. Normalize that phase to texture unit zero
|
||||
// instead of synchronously reading driver binding state.
|
||||
_gl.ActiveTexture(TextureUnit.Texture0);
|
||||
Wb.RenderStateCache.CurrentAtlas = 0;
|
||||
_gl.BindTexture(TextureTarget.Texture2DArray, name);
|
||||
_gl.TexStorage3D(
|
||||
TextureTarget.Texture2DArray,
|
||||
levels: 1,
|
||||
SizedInternalFormat.Rgba8,
|
||||
checked((uint)width),
|
||||
checked((uint)height),
|
||||
checked((uint)capacity));
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureBaseLevel, 0);
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMaxLevel, 0);
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
|
||||
_gl.TexParameter(TextureTarget.Texture2DArray, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
|
||||
handle = _bindless.GetResidentHandle(name);
|
||||
resident = true;
|
||||
Wb.GLHelpers.ThrowOnResourceError(
|
||||
_gl,
|
||||
$"creating composite texture array {width}x{height}x{capacity}");
|
||||
bytes = checked((long)width * height * 4L * capacity);
|
||||
Wb.GpuMemoryTracker.TrackResourceAllocation(Wb.GpuResourceType.Texture);
|
||||
Wb.GpuMemoryTracker.TrackAllocation(bytes, Wb.GpuResourceType.Texture);
|
||||
tracked = true;
|
||||
// Campaign V slice V4t: intern the resident handle into the device's
|
||||
// one texture table. A table-exhaustion throw here is caught by the
|
||||
// same rollback below, and nothing was added to the table if it did.
|
||||
GpuTextureSlot slot = _device.RegisterWorldTextureHandle(handle);
|
||||
return new CompositeTextureArrayResource
|
||||
{
|
||||
Name = name,
|
||||
Handle = handle,
|
||||
Slot = slot,
|
||||
Width = width,
|
||||
Height = height,
|
||||
Capacity = capacity,
|
||||
Bytes = bytes,
|
||||
};
|
||||
}
|
||||
catch (Exception creationFailure)
|
||||
{
|
||||
List<Exception>? cleanupFailures = null;
|
||||
void Attempt(Action cleanup)
|
||||
{
|
||||
try { cleanup(); }
|
||||
catch (Exception ex) { (cleanupFailures ??= []).Add(ex); }
|
||||
}
|
||||
|
||||
bool residencyReleased = !resident;
|
||||
if (resident)
|
||||
{
|
||||
Attempt(() =>
|
||||
{
|
||||
_bindless.MakeNonResident(handle);
|
||||
Wb.GLHelpers.ThrowOnResourceError(_gl, "rolling back composite texture residency");
|
||||
residencyReleased = true;
|
||||
});
|
||||
}
|
||||
if (residencyReleased)
|
||||
{
|
||||
Attempt(() =>
|
||||
{
|
||||
_gl.DeleteTexture(name);
|
||||
Wb.GLHelpers.ThrowOnResourceError(_gl, "rolling back composite texture array");
|
||||
if (tracked)
|
||||
{
|
||||
Wb.GpuMemoryTracker.TrackDeallocation(bytes, Wb.GpuResourceType.Texture);
|
||||
Wb.GpuMemoryTracker.TrackResourceDeallocation(Wb.GpuResourceType.Texture);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (cleanupFailures is not null)
|
||||
{
|
||||
cleanupFailures.Insert(0, creationFailure);
|
||||
throw new AggregateException(
|
||||
"Composite texture-array construction and rollback both failed.",
|
||||
cleanupFailures);
|
||||
}
|
||||
throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_gl.BindTexture(TextureTarget.Texture2DArray, 0);
|
||||
_gl.ActiveTexture(TextureUnit.Texture0);
|
||||
}
|
||||
}
|
||||
|
||||
public void Upload(CompositeTextureArrayResource resource, int layer, byte[] rgba)
|
||||
{
|
||||
_gl.ActiveTexture(TextureUnit.Texture0);
|
||||
Wb.RenderStateCache.CurrentAtlas = 0;
|
||||
try
|
||||
{
|
||||
_gl.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
|
||||
_gl.BindTexture(TextureTarget.Texture2DArray, resource.Name);
|
||||
fixed (byte* pixels = rgba)
|
||||
{
|
||||
_gl.TexSubImage3D(
|
||||
TextureTarget.Texture2DArray,
|
||||
level: 0,
|
||||
xoffset: 0,
|
||||
yoffset: 0,
|
||||
zoffset: layer,
|
||||
checked((uint)resource.Width),
|
||||
checked((uint)resource.Height),
|
||||
depth: 1,
|
||||
PixelFormat.Rgba,
|
||||
PixelType.UnsignedByte,
|
||||
pixels);
|
||||
}
|
||||
Wb.GLHelpers.ThrowOnResourceError(
|
||||
_gl,
|
||||
$"uploading composite texture layer {layer} ({resource.Width}x{resource.Height})");
|
||||
}
|
||||
finally
|
||||
{
|
||||
_gl.BindTexture(TextureTarget.Texture2DArray, 0);
|
||||
_gl.BindBuffer(BufferTargetARB.PixelUnpackBuffer, 0);
|
||||
_gl.ActiveTexture(TextureUnit.Texture0);
|
||||
}
|
||||
}
|
||||
|
||||
public void MakeNonResident(CompositeTextureArrayResource resource)
|
||||
{
|
||||
Wb.GLHelpers.ThrowOnResourceError(
|
||||
_gl,
|
||||
$"releasing composite texture handle {resource.Handle} (precondition)");
|
||||
// Campaign V slice V4t: retire the table entry before the handle it
|
||||
// names stops being resident. Idempotent, so this stays correct when
|
||||
// the retryable release ledger re-runs the operation.
|
||||
_device.ReleaseWorldTextureHandle(resource.Handle);
|
||||
_bindless.MakeNonResident(resource.Handle);
|
||||
Wb.GLHelpers.ThrowOnResourceError(_gl, $"releasing composite texture handle {resource.Handle}");
|
||||
}
|
||||
|
||||
public void Delete(CompositeTextureArrayResource resource)
|
||||
{
|
||||
Wb.GLHelpers.ThrowOnResourceError(
|
||||
_gl,
|
||||
$"deleting composite texture array {resource.Name} (precondition)");
|
||||
_gl.DeleteTexture(resource.Name);
|
||||
Wb.GLHelpers.ThrowOnResourceError(_gl, $"deleting composite texture array {resource.Name}");
|
||||
Wb.GpuMemoryTracker.TrackDeallocation(resource.Bytes, Wb.GpuResourceType.Texture);
|
||||
Wb.GpuMemoryTracker.TrackResourceDeallocation(Wb.GpuResourceType.Texture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Campaign V slice V6i-2: the backend-neutral composite array backend.
|
||||
///
|
||||
|
|
@ -525,25 +337,6 @@ internal sealed class CompositeTextureArrayCache : IDisposable
|
|||
Accounted,
|
||||
}
|
||||
|
||||
public CompositeTextureArrayCache(
|
||||
GL gl,
|
||||
Wb.BindlessSupport bindless,
|
||||
GlGpuDevice device,
|
||||
IGpuResourceRetirementQueue retirementQueue,
|
||||
long unownedBudgetBytes = DefaultUnownedBudgetBytes,
|
||||
long physicalBudgetBytes = DefaultPhysicalBudgetBytes,
|
||||
int maximumUploadsPerFrame = DefaultMaximumUploadsPerFrame,
|
||||
long maximumUploadBytesPerFrame = DefaultMaximumUploadBytesPerFrame)
|
||||
: this(
|
||||
new GlCompositeTextureArrayBackend(gl, bindless, device),
|
||||
retirementQueue,
|
||||
unownedBudgetBytes,
|
||||
physicalBudgetBytes,
|
||||
maximumUploadsPerFrame,
|
||||
maximumUploadBytesPerFrame)
|
||||
{
|
||||
}
|
||||
|
||||
internal CompositeTextureArrayCache(
|
||||
ICompositeTextureArrayBackend backend,
|
||||
IGpuResourceRetirementQueue retirementQueue,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue