namespace AcDream.App.Rendering.Gpu;
///
/// A GPU buffer. Disposal does not free immediately: every backend routes the
/// physical release through the device's retirement queue so the memory outlives
/// any frame still referencing it. That is the same contract
/// GpuFrameFlightController already enforces for GL names today.
///
internal interface IGpuBuffer : IDisposable
{
string Name { get; }
long SizeBytes { get; }
GpuBufferUsage Usage { get; }
GpuMemoryResidency Residency { get; }
///
/// Writes at . On a
/// buffer this stages through a
/// transfer; on a host-writable buffer it is a direct memory write. Per-frame
/// data should not use this at all — take a ring allocation and write into it.
///
void Upload(long offsetBytes, ReadOnlySpan data);
///
/// Device-side copy, used by the mesh arena's grow-and-copy migration so
/// arena growth never round-trips through system memory.
///
void CopyTo(IGpuBuffer destination, long sourceOffsetBytes, long destinationOffsetBytes, long byteCount);
///
/// Reads back into . Only valid on
/// buffers; diagnostics only.
///
void Read(long offsetBytes, Span destination);
}
/// A sampled texture or an attachment image.
internal interface IGpuTexture : IDisposable
{
string Name { get; }
GpuTextureKind Kind { get; }
GpuTextureFormat Format { get; }
int Width { get; }
int Height { get; }
int LayerCount { get; }
int MipLevelCount { get; }
///
/// Uploads one mip level of one array layer. is raw
/// texels for uncompressed formats and raw blocks for BC formats.
///
void Upload(int mipLevel, int layer, ReadOnlySpan data);
///
/// Fills mip levels 1..N-1 from level 0.
///
/// Explicit rather than automatic because the two backends cannot do this the
/// same way: GL calls glGenerateMipmap, while Vulkan blits uncompressed
/// images and CANNOT blit compressed ones. For BC formats the Vulkan backend
/// requires the caller to have supplied a CPU-built chain via
/// and this call throws — the GL path's reliance on
/// driver-defined compressed-mip regeneration is the behaviour we are
/// deliberately not carrying forward.
///
void GenerateMipChain();
}
/// Immutable sampler state. Owned and de-duplicated by the device.
internal interface IGpuSampler : IDisposable
{
GpuSamplerDescription Description { get; }
}
///
/// A compiled shader program plus every piece of fixed pipeline state it draws
/// with. This is the type that replaces the imperative
/// Enable/BlendFunc/DepthMask/CullFace brackets scattered through the GL
/// renderers: state that Vulkan bakes at creation lives here, and only the state
/// core Vulkan 1.3 makes dynamic stays callable per draw
/// ( and friends).
///
internal interface IGpuPipeline : IDisposable
{
GpuPipelineDescription Description { get; }
}
/// An offscreen render target whose colour attachment is sampleable once the pass ends.
internal interface IGpuRenderTarget : IDisposable
{
GpuRenderTargetDescription Description { get; }
/// The colour attachment, for registering into the texture table or blitting into UI.
IGpuTexture ColorTexture { get; }
}
///
/// GPU-side timing. Backed by GL TimeElapsed queries or Vulkan timestamp
/// queries; results are only readable once the issuing frame has retired, so
/// reports the most recent completed measurement rather
/// than blocking.
///
internal interface IGpuTimerPool
{
/// True when the backend can measure GPU time at all.
bool IsSupported { get; }
/// Milliseconds measured for in the most recent retired frame.
bool TryResolve(string scopeName, out double milliseconds);
}