acdream/src/AcDream.App/Rendering/Gpu/IGpuDevice.cs

96 lines
4.3 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}