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
|
|
@ -30,7 +30,6 @@ using AcDream.Runtime.Entities;
|
|||
using AcDream.Runtime.World;
|
||||
using DatReaderWriter;
|
||||
using DatReaderWriter.DBObjs;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
|
||||
namespace AcDream.App.Composition;
|
||||
|
|
@ -678,46 +677,28 @@ internal sealed class LivePresentationCompositionPhase
|
|||
AlphaScratchBudgetProfile.Create(
|
||||
d.Options.ResidencyBudgets.AlphaScratchBytes);
|
||||
|
||||
// Campaign V slice V6h: every renderer below this line is still raw GL.
|
||||
// On a backend without a GL context none of them is constructed, and the
|
||||
// CPU owners this phase also produces — entity lifetime, motion,
|
||||
// selection, effects, lights, the landblock pipeline — run unchanged.
|
||||
GL? gl = d.Graphics.Gl;
|
||||
var selectionScene = new RetailSelectionScene(
|
||||
new RetailSelectionGeometryCache(content.Dats, d.DatLock));
|
||||
// Campaign V slice V6j: the world dispatcher exists on BOTH arms. The GL
|
||||
// arm is unchanged; the RHI arm records into the pass the world scene
|
||||
// phase publishes on this scope.
|
||||
// Campaign V slice V6j: the world dispatcher records into the pass the
|
||||
// world scene phase publishes on this scope. The raw-GL arm was
|
||||
// deleted at slice V11.
|
||||
IWorldPassScope? worldPassScope = d.Graphics.WorldPassScope;
|
||||
var dispatcherLease = scope.Acquire(
|
||||
"WB draw dispatcher",
|
||||
() => gl is not null
|
||||
? new WbDrawDispatcher(
|
||||
gl,
|
||||
foundation.MeshShader!,
|
||||
foundation.TextureCache,
|
||||
foundation.MeshAdapter!,
|
||||
entitySpawnAdapter,
|
||||
foundation.Bindless!,
|
||||
d.ClassificationCache,
|
||||
d.TranslucencyFades,
|
||||
selectionScene,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.DispatcherBytes)
|
||||
: new WbDrawDispatcher(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"A backend without a GL context must publish a world pass scope."),
|
||||
foundation.TextureCache,
|
||||
foundation.MeshAdapter!,
|
||||
entitySpawnAdapter,
|
||||
d.ClassificationCache,
|
||||
d.TranslucencyFades,
|
||||
selectionScene,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.DispatcherBytes),
|
||||
() => new WbDrawDispatcher(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
foundation.TextureCache,
|
||||
foundation.MeshAdapter!,
|
||||
entitySpawnAdapter,
|
||||
d.ClassificationCache,
|
||||
d.TranslucencyFades,
|
||||
selectionScene,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.DispatcherBytes),
|
||||
static value => value.Dispose());
|
||||
var selectionQuery = new WorldSelectionQuery(
|
||||
liveEntities,
|
||||
|
|
@ -815,8 +796,9 @@ internal sealed class LivePresentationCompositionPhase
|
|||
paperdollLease = scope.Acquire(
|
||||
"paperdoll viewport",
|
||||
() => new PaperdollViewportRenderer(
|
||||
gl,
|
||||
worldPassScope,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
paperdollDispatcher,
|
||||
|
|
@ -861,8 +843,9 @@ internal sealed class LivePresentationCompositionPhase
|
|||
creatureAppraisalLease = scope.Acquire(
|
||||
"creature appraisal viewport",
|
||||
() => new CreatureAppraisalViewportRenderer(
|
||||
gl,
|
||||
worldPassScope,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
appraisalDispatcher,
|
||||
|
|
@ -897,24 +880,17 @@ internal sealed class LivePresentationCompositionPhase
|
|||
var envCellFrustum = new WbFrustum();
|
||||
var envCellLease = scope.Acquire(
|
||||
"environment-cell renderer",
|
||||
() => gl is not null
|
||||
? new EnvCellRenderer(
|
||||
gl,
|
||||
foundation.MeshAdapter!.MeshManager!,
|
||||
envCellFrustum)
|
||||
: new EnvCellRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"A backend without a GL context must publish a world pass scope."),
|
||||
foundation.MeshAdapter!.MeshManager!,
|
||||
envCellFrustum),
|
||||
() => new EnvCellRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
foundation.MeshAdapter!.MeshManager!,
|
||||
envCellFrustum),
|
||||
static value => value.Dispose());
|
||||
// The RHI arm's three pipelines ARE its program, built at construction,
|
||||
// so only the GL arm has a second initialisation step.
|
||||
if (foundation.MeshShader is { } envCellShader)
|
||||
envCellLease.Resource.Initialize(envCellShader);
|
||||
// The three pipelines ARE its program, built at construction — the
|
||||
// raw-GL arm's separate Initialize(Shader) step was deleted at V11.
|
||||
Fault(LivePresentationCompositionPoint.EnvironmentCellsCreated);
|
||||
|
||||
// The streaming pipeline itself is backend-neutral and runs on both
|
||||
|
|
@ -972,20 +948,18 @@ internal sealed class LivePresentationCompositionPhase
|
|||
"portal clip frame",
|
||||
ClipFrame.NoClip,
|
||||
static value => value.Dispose());
|
||||
// Campaign V slice V6l: the portal depth mask exists on BOTH arms. The
|
||||
// GL arm keeps its inline program and raw draws; the RHI arm compiles
|
||||
// portal_depth from SPIR-V into three pipelines and records into the
|
||||
// pass the world scene phase publishes on this scope.
|
||||
// Campaign V slice V6l: the portal depth mask compiles portal_depth
|
||||
// from SPIR-V into three pipelines and records into the pass the
|
||||
// world scene phase publishes on this scope. The raw-GL inline
|
||||
// program and raw draws were deleted at slice V11.
|
||||
var portalDepthLease = scope.Acquire(
|
||||
"portal depth mask",
|
||||
() => gl is not null
|
||||
? new PortalDepthMaskRenderer(gl)
|
||||
: new PortalDepthMaskRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"A backend without a GL context must publish a world pass scope.")),
|
||||
() => new PortalDepthMaskRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope.")),
|
||||
static value => value.Dispose());
|
||||
CompositionAcquisitionScope.CompositionAcquisitionLease<
|
||||
PortalWaitNoticeController>? portalWaitNoticeLease = null;
|
||||
|
|
@ -1003,11 +977,9 @@ internal sealed class LivePresentationCompositionPhase
|
|||
: null;
|
||||
CompositionAcquisitionScope.CompositionAcquisitionLease<
|
||||
PortalTunnelPresentation>? portalTunnelLease = null;
|
||||
// Campaign V slice V6m: portal space exists on BOTH arms. The GL arm is
|
||||
// unchanged; the RHI arm opens a backbuffer pass of its own and publishes
|
||||
// it on the scope for the span of the draw, the way the two offscreen
|
||||
// viewports do. It was the last raw-GL world-adjacent renderer, so the
|
||||
// Vulkan arm no longer composes a portal-less teleport presentation.
|
||||
// Campaign V slice V6m: portal space opens a backbuffer pass of its
|
||||
// own and publishes it on the scope for the span of the draw, the way
|
||||
// the two offscreen viewports do. The raw-GL arm was deleted at V11.
|
||||
if (dispatcherLease.Resource is { } portalDispatcher)
|
||||
{
|
||||
PortalTunnelPresentation portalTunnel;
|
||||
|
|
@ -1015,8 +987,9 @@ internal sealed class LivePresentationCompositionPhase
|
|||
{
|
||||
portalTunnel = d.PortalTunnelFallback.AcquirePrepared(
|
||||
() => PortalTunnelPresentation.CreateRequired(
|
||||
gl,
|
||||
worldPassScope,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
host.GpuFrameLifetime,
|
||||
content.Dats,
|
||||
content.AnimationLoader,
|
||||
|
|
@ -1051,87 +1024,45 @@ internal sealed class LivePresentationCompositionPhase
|
|||
}
|
||||
Fault(LivePresentationCompositionPoint.PortalResourcesCreated);
|
||||
|
||||
AcDream.App.Rendering.Shader? skyShader = gl is null
|
||||
? null
|
||||
: d.RenderResourceLifetime.AcquireSkyShader(
|
||||
() => new AcDream.App.Rendering.Shader(
|
||||
gl,
|
||||
Path.Combine(foundation.ShadersDirectory, "sky.vert"),
|
||||
Path.Combine(foundation.ShadersDirectory, "sky.frag"),
|
||||
// Campaign V slice V6e: sky reads the shared texture table and
|
||||
// ACDREAM_UBO_SET now, both of which common.glsl declares.
|
||||
includeCommonPreamble: true));
|
||||
var skyShaderLease = skyShader is null
|
||||
? null
|
||||
: scope.Own(
|
||||
"sky shader lifetime",
|
||||
skyShader,
|
||||
_ => d.RenderResourceLifetime.ReleaseSkyShader());
|
||||
// Campaign V slice V6k: the sky exists on BOTH arms. The GL arm is
|
||||
// unchanged except for where its table slots come from; the RHI arm
|
||||
// compiles the sky pair from SPIR-V and records into the pass the world
|
||||
// scene phase publishes on this scope.
|
||||
// Campaign V slice V6k: the sky compiles its pair from SPIR-V and
|
||||
// records into the pass the world scene phase publishes on this
|
||||
// scope. The raw-GL arm — its own shader pair (acquired through
|
||||
// GameRenderResourceLifetime.AcquireSkyShader, deleted with it) and
|
||||
// its own bindless/device-table wiring — was deleted at slice V11.
|
||||
var skyLease = scope.Acquire(
|
||||
"sky renderer",
|
||||
() => gl is not null
|
||||
? new SkyRenderer(
|
||||
gl,
|
||||
content.Dats,
|
||||
skyShader!,
|
||||
foundation.TextureCache,
|
||||
foundation.Samplers!,
|
||||
// Slice V6e: the sky samples through the shared texture table,
|
||||
// so it needs the same bindless entry point the world path uses.
|
||||
foundation.Bindless!,
|
||||
// Slice V6k: and V4t's world-handle seam on the device, which
|
||||
// retired the last per-renderer GlBindlessHandleTable.
|
||||
(AcDream.App.Rendering.Gpu.Gl.GlGpuDevice)host.GpuDevice)
|
||||
{
|
||||
// Campaign V slice V7: null unless ACDREAM_SKY_PHASE_SECONDS
|
||||
// is set, which is every run but a differential gate's.
|
||||
AnimationPhaseSecondsOverride = d.Options.SkyAnimationPhaseSeconds,
|
||||
}
|
||||
: new SkyRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"A backend without a GL context must publish a world pass scope."),
|
||||
content.Dats,
|
||||
foundation.TextureCache)
|
||||
{
|
||||
AnimationPhaseSecondsOverride = d.Options.SkyAnimationPhaseSeconds,
|
||||
},
|
||||
() => new SkyRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
content.Dats,
|
||||
foundation.TextureCache)
|
||||
{
|
||||
// Campaign V slice V7: null unless ACDREAM_SKY_PHASE_SECONDS
|
||||
// is set, which is every run but a differential gate's.
|
||||
AnimationPhaseSecondsOverride = d.Options.SkyAnimationPhaseSeconds,
|
||||
},
|
||||
static value => value.Dispose());
|
||||
// Campaign V slice V6l: particles exist on BOTH arms. The GL arm is
|
||||
// unchanged; the RHI arm compiles the two particle pairs from SPIR-V,
|
||||
// draws instances through the vertex binding the V6l contract amendment
|
||||
// added, and records into the pass the world scene phase publishes on
|
||||
// this scope.
|
||||
// Campaign V slice V6l: the RHI arm compiles the two particle pairs
|
||||
// from SPIR-V, draws instances through the vertex binding the V6l
|
||||
// contract amendment added, and records into the pass the world scene
|
||||
// phase publishes on this scope. The raw-GL arm was deleted at V11.
|
||||
var particleLease = scope.AcquireOptional(
|
||||
"particle renderer",
|
||||
() => gl is not null
|
||||
? new ParticleRenderer(
|
||||
gl,
|
||||
foundation.ShadersDirectory,
|
||||
content.ParticleSystem,
|
||||
foundation.TextureCache,
|
||||
content.Dats,
|
||||
foundation.MeshAdapter!,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.ParticleBytes)
|
||||
: new ParticleRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"A backend without a GL context must publish a world pass scope."),
|
||||
content.ParticleSystem,
|
||||
foundation.TextureCache,
|
||||
content.Dats,
|
||||
foundation.MeshAdapter!,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.ParticleBytes),
|
||||
() => new ParticleRenderer(
|
||||
host.GpuDevice,
|
||||
host.GpuFrameLifetime,
|
||||
worldPassScope
|
||||
?? throw new InvalidOperationException(
|
||||
"The graphics backend must publish a world pass scope."),
|
||||
content.ParticleSystem,
|
||||
foundation.TextureCache,
|
||||
content.Dats,
|
||||
foundation.MeshAdapter!,
|
||||
d.RetailAlphaQueue,
|
||||
alphaScratchBudgets.ParticleBytes),
|
||||
static value => value.Dispose());
|
||||
Fault(LivePresentationCompositionPoint.SkyAndParticlesCreated);
|
||||
|
||||
|
|
@ -1252,7 +1183,6 @@ internal sealed class LivePresentationCompositionPhase
|
|||
portalTunnelLease?.Transfer();
|
||||
portalWaitNoticeLease?.Transfer();
|
||||
skyLease.Transfer();
|
||||
skyShaderLease?.Transfer();
|
||||
particleLease.Transfer();
|
||||
bindingsLease.Transfer();
|
||||
Fault(LivePresentationCompositionPoint.ResultPublished);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue