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