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
|
|
@ -16,7 +16,6 @@ using AcDream.Runtime.Session;
|
|||
using DatReaderWriter;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.Maths;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
|
||||
namespace AcDream.App.Rendering;
|
||||
|
|
@ -56,15 +55,11 @@ public sealed class GameWindow :
|
|||
AcDream.UI.Abstractions.Settings.QualityPreset.High);
|
||||
private IInputContext? _input;
|
||||
private TerrainModernRenderer? _terrain;
|
||||
/// <summary>Phase N.5b: terrain_modern.vert/.frag program. Owned by
|
||||
/// <see cref="_terrain"/> at draw time but allocated + disposed here.</summary>
|
||||
private Shader? _terrainModernShader;
|
||||
private CameraController? _cameraController;
|
||||
private IDatReaderWriter? _dats;
|
||||
private IPreparedAssetSource? _preparedAssets;
|
||||
private readonly AcDream.App.Input.PointerPositionState _pointerPosition = new();
|
||||
private AcDream.App.Input.CameraPointerInputController? _cameraPointerInput;
|
||||
private Shader? _meshShader;
|
||||
private TextureCache? _textureCache;
|
||||
/// <summary>Phase N.4+: WB-backed rendering pipeline adapter. Always non-null
|
||||
/// after <c>OnLoad</c> completes (modern path is mandatory as of N.5).</summary>
|
||||
|
|
@ -77,11 +72,6 @@ public sealed class GameWindow :
|
|||
private AcDream.App.Rendering.Selection.RetailSelectionScene? _retailSelectionScene;
|
||||
private AcDream.App.Interaction.WorldSelectionQuery? _worldSelectionQuery;
|
||||
private AcDream.App.Interaction.SelectionInteractionController? _selectionInteractions;
|
||||
/// <summary>Phase N.5: ARB_bindless_texture + ARB_shader_draw_parameters
|
||||
/// support. Required at startup — missing bindless throws
|
||||
/// <see cref="NotSupportedException"/> in <c>OnLoad</c>.</summary>
|
||||
private AcDream.App.Rendering.Wb.BindlessSupport? _bindlessSupport;
|
||||
private SamplerCache? _samplerCache;
|
||||
private DebugLineRenderer? _debugLines;
|
||||
// K-fix4 (2026-04-26): default OFF. The orange BSP / green cylinder
|
||||
// wireframes are noisy outdoors and confuse first-time users into
|
||||
|
|
@ -128,8 +118,8 @@ public sealed class GameWindow :
|
|||
private readonly AcDream.App.Rendering.GameFrameGraphSlot _frameGraphs = new();
|
||||
private readonly AcDream.App.Rendering.GameRenderResourceLifetime
|
||||
_renderResourceLifetime = new();
|
||||
private readonly AcDream.App.Rendering.GlConstructionCleanupLedger
|
||||
_glConstructionCleanup = new();
|
||||
private readonly AcDream.App.Rendering.ResourceConstructionCleanupLedger
|
||||
_constructionCleanup = new();
|
||||
private readonly AcDream.App.World.WorldEnvironmentController _worldEnvironment;
|
||||
private readonly GameWindowLifetime _lifetime = new();
|
||||
private readonly DisplayFramePacingController _displayFramePacing;
|
||||
|
|
@ -518,7 +508,6 @@ public sealed class GameWindow :
|
|||
private readonly AcDream.UI.Abstractions.Input.KeyBindings _keyBindings;
|
||||
private readonly GraphicalHostPlatformServices _platformServices;
|
||||
private readonly ApplicationPathSet _applicationPaths;
|
||||
private GraphicalCapabilityRecord? _graphicalCapabilities;
|
||||
|
||||
private static AcDream.UI.Abstractions.Input.KeyBindings LoadStartupKeyBindings(
|
||||
string path)
|
||||
|
|
@ -687,8 +676,7 @@ public sealed class GameWindow :
|
|||
// attribute, so it must come from this same snapshot rather than a
|
||||
// second settings load during OnLoad.
|
||||
RuntimeSettingsSnapshot startup = _runtimeSettings.Startup;
|
||||
if (_options.RenderBackend == RenderBackendKind.Vulkan
|
||||
&& _options.VulkanCapabilityProbe)
|
||||
if (_options.VulkanCapabilityProbe)
|
||||
{
|
||||
// Campaign V slice V6h reduced the V5 bring-up host to what its name
|
||||
// says: a capability probe. It opens its own window, runs the gate,
|
||||
|
|
@ -706,39 +694,17 @@ public sealed class GameWindow :
|
|||
|
||||
FramePacingPolicy startupPacing =
|
||||
_displayFramePacing.InitializeStartup(startup.Display.VSync);
|
||||
// Campaign V slice V6h: the ONLY startup difference between the two
|
||||
// backends. Vulkan needs a client-API-less window (the surface comes from
|
||||
// VK_KHR_surface), and neither MSAA nor the stencil bit count is a window
|
||||
// Vulkan needs a client-API-less window (the surface comes from
|
||||
// VK_KHR_surface); neither MSAA nor the stencil bit count is a window
|
||||
// attribute there — both are attachment properties the RHI device
|
||||
// configures, so they are passed to VulkanGraphicsContext instead.
|
||||
var options = _options.RenderBackend == RenderBackendKind.Vulkan
|
||||
? WindowOptions.DefaultVulkan with
|
||||
{
|
||||
Size = new Vector2D<int>(1280, 720),
|
||||
Title = "acdream — Vulkan",
|
||||
VSync = startupPacing.UseVSync,
|
||||
}
|
||||
: WindowOptions.Default with
|
||||
{
|
||||
Size = new Vector2D<int>(1280, 720),
|
||||
Title = "acdream — phase 1",
|
||||
API = new GraphicsAPI(
|
||||
ContextAPI.OpenGL,
|
||||
ContextProfile.Core,
|
||||
ContextFlags.ForwardCompatible,
|
||||
new APIVersion(4, 3)),
|
||||
VSync = startupPacing.UseVSync,
|
||||
// A.5 T22.5: MSAA from quality preset (0 = disabled, 2/4/8 = multisample).
|
||||
// Silk.NET passes this to SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES).
|
||||
// Cannot be changed at runtime; Quality changes mid-session that would
|
||||
// alter MsaaSamples are logged as a restart-required warning.
|
||||
Samples = startup.Quality.MsaaSamples,
|
||||
// #117 (2026-06-11): the aperture punch's depth gate needs a
|
||||
// stencil buffer (PortalDepthMaskRenderer two-pass mark+punch).
|
||||
// GLFW defaults to 8 stencil bits, but make the requirement
|
||||
// explicit rather than platform-implicit.
|
||||
PreferredStencilBufferBits = 8,
|
||||
};
|
||||
// configures instead. The raw-GL window options this used to fork to
|
||||
// were deleted at Campaign V slice V11.
|
||||
var options = WindowOptions.DefaultVulkan with
|
||||
{
|
||||
Size = new Vector2D<int>(1280, 720),
|
||||
Title = "acdream — Vulkan",
|
||||
VSync = startupPacing.UseVSync,
|
||||
};
|
||||
_startupPacing = startupPacing;
|
||||
_startupQuality = startup.Quality;
|
||||
|
||||
|
|
@ -766,7 +732,7 @@ public sealed class GameWindow :
|
|||
}
|
||||
catch (Exception failure)
|
||||
{
|
||||
_glConstructionCleanup.RetainFrom(failure);
|
||||
_constructionCleanup.RetainFrom(failure);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
|
@ -912,19 +878,6 @@ public sealed class GameWindow :
|
|||
_audioSink = value.HookSink;
|
||||
}
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishBindlessSupport(
|
||||
BindlessSupport value) =>
|
||||
PublishCompositionOwner(
|
||||
ref _bindlessSupport,
|
||||
value,
|
||||
"bindless support");
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishTerrainShader(Shader value) =>
|
||||
PublishCompositionOwner(
|
||||
ref _terrainModernShader,
|
||||
value,
|
||||
"terrain shader");
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishSceneLighting(
|
||||
SceneLightingUboBinding value) =>
|
||||
PublishCompositionOwner(
|
||||
|
|
@ -975,9 +928,6 @@ public sealed class GameWindow :
|
|||
_surfaceCache = surfaceCache;
|
||||
}
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishMeshShader(Shader value) =>
|
||||
PublishCompositionOwner(ref _meshShader, value, "mesh shader");
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishWbMeshAdapter(
|
||||
WbMeshAdapter value) =>
|
||||
PublishCompositionOwner(ref _wbMeshAdapter, value, "WB mesh adapter");
|
||||
|
|
@ -986,10 +936,6 @@ public sealed class GameWindow :
|
|||
TextureCache value) =>
|
||||
PublishCompositionOwner(ref _textureCache, value, "texture cache");
|
||||
|
||||
void IGameWindowWorldRenderPublication.PublishSamplerCache(
|
||||
SamplerCache value) =>
|
||||
PublishCompositionOwner(ref _samplerCache, value, "sampler cache");
|
||||
|
||||
void IGameWindowInteractionRetainedUiPublication.PublishInteractionRetainedUi(
|
||||
InteractionRetainedUiResult result)
|
||||
{
|
||||
|
|
@ -1192,41 +1138,31 @@ public sealed class GameWindow :
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Campaign V slice V6h: how the UI probe reads a completed frame.
|
||||
///
|
||||
/// <para><see cref="FrameScreenshotController"/> applies the bottom-up flip
|
||||
/// <c>glReadPixels</c> needs, so GL hands it the raw read and Vulkan — whose
|
||||
/// <see cref="IGpuDevice.CaptureBackbuffer"/> is documented top-left-origin —
|
||||
/// pre-flips so the two cancel. Routing GL through the same
|
||||
/// <c>CaptureBackbuffer</c> seam would double-flip, which is exactly the kind
|
||||
/// of "usually right" instrument §5.5 of the campaign plan spent three
|
||||
/// slices removing.</para>
|
||||
/// How the UI probe reads a completed frame.
|
||||
/// <see cref="IGpuDevice.CaptureBackbuffer"/> is documented top-left-origin,
|
||||
/// so <see cref="FrameScreenshotController"/> flips it to match the PNG's
|
||||
/// row order. The raw-GL read this used to fork from — whose rows already
|
||||
/// come out bottom-up, needing no flip — was deleted at Campaign V slice
|
||||
/// V11.
|
||||
/// </summary>
|
||||
private static Func<int, int, byte[]> CreateBackbufferReader(
|
||||
GameWindowGraphics graphics,
|
||||
IGpuDevice device) =>
|
||||
graphics.Gl is { } gl
|
||||
? (width, height) =>
|
||||
AcDream.App.Diagnostics.FrameScreenshotController
|
||||
.ReadDefaultFramebuffer(gl, width, height)
|
||||
: (width, height) =>
|
||||
AcDream.App.Diagnostics.FrameScreenshotController.FlipRows(
|
||||
device.CaptureBackbuffer(width, height),
|
||||
width,
|
||||
height);
|
||||
(width, height) =>
|
||||
AcDream.App.Diagnostics.FrameScreenshotController.FlipRows(
|
||||
device.CaptureBackbuffer(width, height),
|
||||
width,
|
||||
height);
|
||||
|
||||
/// <summary>
|
||||
/// Campaign V slice V6h: the backend fork, in one expression. Vulkan's
|
||||
/// context acquisition runs its own capability gate inside
|
||||
/// Vulkan's context acquisition runs its own capability gate inside
|
||||
/// <see cref="AcDream.App.Rendering.Gpu.Vk.VulkanGraphicsContext.Acquire"/>,
|
||||
/// throwing <see cref="NotSupportedException"/> into the same exit-code-4
|
||||
/// contract <c>Program.cs</c> publishes for GL.
|
||||
/// contract <c>Program.cs</c> publishes. The raw-GL fork this used to make
|
||||
/// was deleted at Campaign V slice V11.
|
||||
/// </summary>
|
||||
private GameWindowGraphics CreateGraphics()
|
||||
{
|
||||
if (_options.RenderBackend != RenderBackendKind.Vulkan)
|
||||
return new OpenGlGameWindowGraphics(GL.GetApi(_window!));
|
||||
|
||||
AcDream.App.Rendering.Gpu.Vk.VulkanGraphicsContext vulkan =
|
||||
AcDream.App.Rendering.Gpu.Vk.VulkanGraphicsContext.Acquire(
|
||||
_window!,
|
||||
|
|
@ -1245,32 +1181,10 @@ public sealed class GameWindow :
|
|||
// run narrow-phase BSP tests during FindObjCollisions.
|
||||
|
||||
GameWindowPlatformResult<GameWindowGraphics, IInputContext> platform = AcquirePlatform();
|
||||
// The GL capability gate reads GL extension strings, so it runs only on
|
||||
// the GL arm. Vulkan's equivalent gate already ran inside
|
||||
// VulkanGraphicsContext.Acquire and wrote its own report.
|
||||
if (platform.Graphics.Gl is { } capabilityGl)
|
||||
{
|
||||
string capabilityReportPath = Path.Combine(
|
||||
_applicationPaths.DiagnosticsDirectory,
|
||||
"graphical-capabilities.json");
|
||||
_graphicalCapabilities =
|
||||
GraphicalCapabilityGuard.CaptureVerifyAndWrite(
|
||||
capabilityGl,
|
||||
_window!,
|
||||
platform.Input,
|
||||
_platformServices,
|
||||
capabilityReportPath);
|
||||
GraphicalCapabilityGuard.ThrowIfUnsupported(
|
||||
_graphicalCapabilities,
|
||||
capabilityReportPath);
|
||||
Console.WriteLine(
|
||||
"graphics: capability gate passed " +
|
||||
$"({_graphicalCapabilities.ActiveDisplayProtocol}, " +
|
||||
$"{_graphicalCapabilities.GlVendor}, " +
|
||||
$"{_graphicalCapabilities.GlRenderer}, " +
|
||||
$"{_graphicalCapabilities.GlVersion}); " +
|
||||
$"report={capabilityReportPath}");
|
||||
}
|
||||
// The raw-GL capability gate that used to run here (reading GL
|
||||
// extension strings) was deleted at Campaign V slice V11. Vulkan's
|
||||
// equivalent gate already ran inside VulkanGraphicsContext.Acquire and
|
||||
// wrote its own report.
|
||||
|
||||
GameWindowCompositionPipeline.Run<
|
||||
GameWindowPlatformResult<GameWindowGraphics, IInputContext>,
|
||||
|
|
@ -1727,12 +1641,9 @@ public sealed class GameWindow :
|
|||
_clipFrame,
|
||||
_skyRenderer,
|
||||
_particleRenderer,
|
||||
_samplerCache,
|
||||
_textureCache,
|
||||
_wbMeshAdapter,
|
||||
_meshShader,
|
||||
_terrain,
|
||||
_terrainModernShader,
|
||||
_sceneLightingUbo,
|
||||
_debugLines,
|
||||
_textRenderer,
|
||||
|
|
@ -1740,7 +1651,7 @@ public sealed class GameWindow :
|
|||
_displayFramePacing,
|
||||
_frameProfiler,
|
||||
_renderResourceLifetime,
|
||||
_glConstructionCleanup),
|
||||
_constructionCleanup),
|
||||
new PlatformShutdownRoots(
|
||||
_dats,
|
||||
_preparedAssets,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue