refactor(render): Campaign V slice V6i-2 commit 3 — the mesh pipeline stops naming a backend
Plan §5.5.10 recorded the blocker as a fact about types: "WbMeshAdapter owns an
OpenGLGraphicsDevice, so it is not constructible on Vulkan until slice V4t" —
which is the entire reason NullWbMeshAdapter exists. §5.5.12 item 6 then measured
how wide that dependency really is, and the answer is seven members out of a
760-line class: a GL context, the retirement queue, the shared instance VBO, and
two capability flags.
IMeshPipelineDevice is exactly that surface. OpenGLGraphicsDevice declares it and
every member already existed under a GL-specific name, so the shipping backend
executes not one changed statement — these are aliases, not behaviour.
Two casts moved, and they are what actually blocked construction:
- ObjectMeshManager downcast IGpuDevice to GlGpuDevice in its CONSTRUCTOR, so a
Vulkan-composed pipeline threw before running a statement. V4t put it there
because the class registered bindless handles itself; commit 2 moved that into
the array, leaving the field a pass-through for the raw-GL renderers' handle
table. The cast now lives on that one property and names the backend it was
composed against instead of reporting a failed cast.
- The atlas array factory is selected by IWorldTextureArrayFactory.For, which is
the one place the texture stack branches on a backend.
MeshPipelineDeviceSeamTests proves the decoupling rather than describing it: it
builds ObjectMeshManager against a device whose Gl is null, asserts it constructs,
asserts construction built no GL object, asserts the handle table refuses by name,
and asserts the factory picks the RHI arm. A reflection test pins the seam's
member set so a later slice cannot quietly widen it back out — the whole value
here is that it is narrow.
What this does NOT claim: the mesh pipeline does not RUN on Vulkan. Its upload
bodies are still raw GL — GlobalMeshBuffer, the VAO/IBO construction, the layer
transfers — and they now fail through one RequireGl() accessor that names the
slice that owns porting them, instead of failing at construction. WbMeshAdapter
still creates an OpenGLGraphicsDevice in its GL constructor, because there is no
second implementation to create yet. Those bodies are items 3–5 of §5.5.12's
remainder list, along with RetailPViewPassExecutor and the three world renderers'
submission arms.
§5.5.13 reports the whole of V6i-2 and the slice table gains its V6i row.
Gates: Release build; App tests 4,109 / 3 skips (the 4,086 baseline plus 23 across
the three commits); complete Release suite 9,172 / 5; strict GL offline pixel gate
vs 0ca802cd 1.60e-05 (9 px of 563,200 — the low end of the documented 9–31 px
control band, and fewer than a same-commit control has measured); GL connected
tools/run-repeat-connected-gate.ps1 -Runs 3 at 3/3 RENDERED on the desktop witness
and 3/3 on the client capture; one Vulkan composition-host run with
VK_LAYER_KHRONOS_validation proven inserted by the loader at zero errors, zero
warnings, no [shutdown] diagnostic, and a captured frame.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
c8d0f70bbe
commit
5b3d72a90c
7 changed files with 459 additions and 18 deletions
58
src/AcDream.App/Rendering/Wb/IMeshPipelineDevice.cs
Normal file
58
src/AcDream.App/Rendering/Wb/IMeshPipelineDevice.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
using AcDream.App.Rendering;
|
||||
using Silk.NET.OpenGL;
|
||||
|
||||
namespace AcDream.App.Rendering.Wb;
|
||||
|
||||
/// <summary>
|
||||
/// Campaign V slice V6i-2: everything the mesh pipeline actually needs from a
|
||||
/// graphics device.
|
||||
///
|
||||
/// <para>Plan §5.5.10 recorded the blocker plainly: "<c>WbMeshAdapter</c> owns an
|
||||
/// <c>OpenGLGraphicsDevice</c>, so it is not constructible on Vulkan" — which is
|
||||
/// why <c>NullWbMeshAdapter</c> exists at all. §5.5.12 item 6 then MEASURED how
|
||||
/// wide that dependency really is, and the answer is this: a GL context, the
|
||||
/// retirement queue, the shared instance VBO, and two capability flags. Seven
|
||||
/// members out of a 760-line class.</para>
|
||||
///
|
||||
/// <para>So the coupling is expressed as an interface at exactly that surface
|
||||
/// and <see cref="OpenGLGraphicsDevice"/> declares it — every member already
|
||||
/// existed, so the GL arm executes not one changed statement. What this buys is
|
||||
/// that <c>ObjectMeshManager</c> and <c>WbMeshAdapter</c> no longer NAME a
|
||||
/// backend, which is the prerequisite for the slice that gives them a second
|
||||
/// implementation.</para>
|
||||
///
|
||||
/// <para><b>What it does not yet buy, stated plainly.</b> <see cref="Gl"/> is
|
||||
/// still a GL type, because the mesh pipeline's upload bodies are still raw GL —
|
||||
/// <c>GlobalMeshBuffer</c>, the VAO/IBO construction, and the layer transfers all
|
||||
/// speak it directly. Those bodies are the pass-structure work items 3–5 of
|
||||
/// §5.5.12's remainder list own. This slice removes the TYPE-level blocker and
|
||||
/// names the rest; it does not claim the mesh pipeline runs on Vulkan today, and
|
||||
/// <see cref="Gl"/> being nullable is what will make the remaining sites fail
|
||||
/// loudly rather than silently when that arm is written.</para>
|
||||
/// </summary>
|
||||
internal interface IMeshPipelineDevice : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// The GL context, or null on a backend that has none. Every reader is a
|
||||
/// raw-GL upload body awaiting its own port.
|
||||
/// </summary>
|
||||
GL? Gl { get; }
|
||||
|
||||
/// <summary>Frame-flight-gated release for everything the pipeline allocates.</summary>
|
||||
IGpuResourceRetirementQueue ResourceRetirement { get; }
|
||||
|
||||
/// <summary>The shared per-instance attribute buffer the legacy draw path binds.</summary>
|
||||
uint InstanceVBO { get; }
|
||||
|
||||
/// <summary><c>GL_ARB_bindless_texture</c>. Half of the modern-path gate.</summary>
|
||||
bool HasBindless { get; }
|
||||
|
||||
/// <summary>GL 4.3 or better. The other half of the modern-path gate.</summary>
|
||||
bool HasOpenGL43 { get; }
|
||||
|
||||
/// <summary>True while deferred device work is still queued.</summary>
|
||||
bool HasPendingWork { get; }
|
||||
|
||||
/// <summary>Runs deferred device work. Called once per frame from the render thread.</summary>
|
||||
void ProcessQueue();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue