96 lines
4.3 KiB
C#
96 lines
4.3 KiB
C#
namespace AcDream.App.Rendering.Gpu;
|
||
|
||
/// <summary>
|
||
/// The RHI root: creates every GPU resource, owns the global texture table, and
|
||
/// drives the frame loop. One instance per graphics context, constructed during
|
||
/// composition and threaded into renderers in place of the raw <c>GL</c> handle.
|
||
/// Resource creation/registration and retirement are safe for one asynchronous
|
||
/// off-side render-pack preparation worker while the render thread records the
|
||
/// active generation. Frame/pass recording and queued-device-action draining
|
||
/// remain render-thread-only.
|
||
///
|
||
/// Campaign V (see <c>docs/plans/2026-07-27-vulkan-campaign.md</c>) implements
|
||
/// this interface twice: first on OpenGL — behaviour-preserving, so each renderer
|
||
/// port is pixel-gated against the previous commit on the shipping backend — and
|
||
/// then on Vulkan, gated by a GL-versus-Vulkan differential. The GL
|
||
/// implementation is deleted at slice V11.
|
||
/// </summary>
|
||
internal interface IGpuDevice : IDisposable
|
||
{
|
||
GpuBackendKind Backend { get; }
|
||
|
||
GpuCapabilityRecord Capabilities { get; }
|
||
|
||
/// <summary>
|
||
/// Frame-flight-gated resource release. Resource disposal routes through here
|
||
/// so nothing is freed while a submitted frame may still reference it.
|
||
/// </summary>
|
||
IGpuResourceRetirementQueue Retirement { get; }
|
||
|
||
/// <summary>GPU timing results from retired frames.</summary>
|
||
IGpuTimerPool Timers { get; }
|
||
|
||
/// <summary>
|
||
/// A registered 1×1 opaque-white texture. Renderers that need a defined
|
||
/// fallback use this rather than assuming slot 0 means anything — an
|
||
/// unregistered <see cref="GpuTextureSlot"/> is
|
||
/// <see cref="GpuTextureSlot.Unassigned"/> and must never reach a shader.
|
||
/// </summary>
|
||
GpuTextureSlot DefaultTextureSlot { get; }
|
||
|
||
IGpuBuffer CreateBuffer(in GpuBufferDescription description);
|
||
|
||
IGpuTexture CreateTexture(in GpuTextureDescription description);
|
||
|
||
/// <summary>Creates or returns a cached sampler; sampler state is de-duplicated by value.</summary>
|
||
IGpuSampler CreateSampler(in GpuSamplerDescription description);
|
||
|
||
/// <summary>
|
||
/// Compiles and links a pipeline. Both backends build every pipeline during
|
||
/// startup, so no frame ever pays a shader-compile or state-revalidation cost.
|
||
/// </summary>
|
||
IGpuPipeline CreatePipeline(GpuPipelineDescription description);
|
||
|
||
IGpuRenderTarget CreateRenderTarget(in GpuRenderTargetDescription description);
|
||
|
||
/// <summary>Creates the dedicated 2-4 cascade sampleable depth array.</summary>
|
||
IGpuDirectionalDepthTarget CreateDirectionalDepthTarget(
|
||
in GpuDirectionalDepthTargetDescription description);
|
||
|
||
/// <summary>
|
||
/// Publishes a (texture, sampler) pair into the global table and returns the
|
||
/// slot shaders index it by. The same texture registered with two samplers
|
||
/// occupies two slots — matching how it holds two bindless handles today.
|
||
/// </summary>
|
||
GpuTextureSlot RegisterTexture(IGpuTexture texture, IGpuSampler sampler);
|
||
|
||
/// <summary>
|
||
/// Returns a slot to the free list. The slot is not reused until the frames
|
||
/// that could still reference it have retired, so eviction (the texture and
|
||
/// mesh caches' LRU) cannot alias a live draw onto a new texture.
|
||
/// </summary>
|
||
void ReleaseTextureSlot(GpuTextureSlot slot);
|
||
|
||
/// <summary>Opens the next frame, waiting for its flight slot to retire first.</summary>
|
||
IGpuFrame BeginFrame();
|
||
|
||
/// <summary>
|
||
/// Defers <paramref name="action"/> to the render thread. Replaces
|
||
/// <c>OpenGLGraphicsDevice.QueueGLAction</c>; loader threads use it to hand
|
||
/// GPU work back to the thread that owns the context or queue.
|
||
/// </summary>
|
||
void QueueDeviceAction(Action action);
|
||
|
||
/// <summary>Runs queued device actions. Called once per frame from the render thread.</summary>
|
||
void ProcessDeviceActions();
|
||
|
||
/// <summary>
|
||
/// Reads the presented image back as tightly packed top-left-origin RGBA8.
|
||
/// This is the seam the automated screenshot gates already use, so the
|
||
/// pixel-comparison tooling is unaffected by the backend swap.
|
||
/// </summary>
|
||
byte[] CaptureBackbuffer(int width, int height);
|
||
|
||
/// <summary>Blocks until all submitted work completes and every pending retirement has run.</summary>
|
||
void WaitIdle();
|
||
}
|