namespace AcDream.App.Rendering.Gpu;
///
/// 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 GL handle.
///
/// Campaign V (see docs/plans/2026-07-27-vulkan-campaign.md) 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.
///
internal interface IGpuDevice : IDisposable
{
GpuBackendKind Backend { get; }
GpuCapabilityRecord Capabilities { get; }
///
/// Frame-flight-gated resource release. Resource disposal routes through here
/// so nothing is freed while a submitted frame may still reference it.
///
IGpuResourceRetirementQueue Retirement { get; }
/// GPU timing results from retired frames.
IGpuTimerPool Timers { get; }
///
/// A registered 1×1 opaque-white texture. Renderers that need a defined
/// fallback use this rather than assuming slot 0 means anything — an
/// unregistered is
/// and must never reach a shader.
///
GpuTextureSlot DefaultTextureSlot { get; }
IGpuBuffer CreateBuffer(in GpuBufferDescription description);
IGpuTexture CreateTexture(in GpuTextureDescription description);
/// Creates or returns a cached sampler; sampler state is de-duplicated by value.
IGpuSampler CreateSampler(in GpuSamplerDescription description);
///
/// Compiles and links a pipeline. Both backends build every pipeline during
/// startup, so no frame ever pays a shader-compile or state-revalidation cost.
///
IGpuPipeline CreatePipeline(GpuPipelineDescription description);
IGpuRenderTarget CreateRenderTarget(in GpuRenderTargetDescription description);
///
/// 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.
///
GpuTextureSlot RegisterTexture(IGpuTexture texture, IGpuSampler sampler);
///
/// 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.
///
void ReleaseTextureSlot(GpuTextureSlot slot);
/// Opens the next frame, waiting for its flight slot to retire first.
IGpuFrame BeginFrame();
///
/// Defers to the render thread. Replaces
/// OpenGLGraphicsDevice.QueueGLAction; loader threads use it to hand
/// GPU work back to the thread that owns the context or queue.
///
void QueueDeviceAction(Action action);
/// Runs queued device actions. Called once per frame from the render thread.
void ProcessDeviceActions();
///
/// 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.
///
byte[] CaptureBackbuffer(int width, int height);
/// Blocks until all submitted work completes and every pending retirement has run.
void WaitIdle();
}