using System.Numerics; namespace AcDream.App.Rendering.Gpu; /// /// The colour attachment for a pass. /// /// /// The offscreen target to render into, or null for the backbuffer. On GL null /// means framebuffer 0; on Vulkan it means the acquired swapchain image (or the /// multisampled scratch image that resolves into it when /// is ). /// /// What happens to existing contents on entry. /// What happens to contents on exit. /// Clear value used when is . internal readonly record struct GpuColorAttachment( IGpuRenderTarget? Target, GpuLoadOp Load, GpuStoreOp Store, Vector4 ClearColor); /// /// The depth/stencil attachment for a pass. Depth is transient in every acdream /// pass — nothing reads it after the frame — so is normally /// , which lets Vulkan skip writing it back to /// memory entirely. /// /// What happens to existing contents on entry. /// What happens to contents on exit. /// Depth clear value. acdream renders with NDC z in [0,1], so far = 1. /// Stencil clear value; #117's portal punch uses the stencil aspect. internal readonly record struct GpuDepthAttachment( GpuLoadOp Load, GpuStoreOp Store, float ClearDepth, uint ClearStencil); /// /// One rendering pass: a set of attachments, their load/store behaviour, and the /// sample count every pipeline used inside must match. /// /// GL has no such object — its "pass" is implicit in whatever framebuffer happens /// to be bound — so making passes explicit is the single largest structural change /// the RHI imposes on the existing renderers. /// /// The transitional path needs no special API. On GL, BeginPass binds the /// target framebuffer and applies load ops, and deliberately does NOT touch /// viewport or scissor — encoders set those explicitly. A renderer being ported /// during Campaign V slices V4a..V4g therefore opens a pass with /// / against the /// backbuffer and gets exactly today's behaviour, while the frame spine still /// owns clears and framebuffer management. Slice V4h converts the spine itself. /// internal sealed record GpuPassDescription { /// Stable identifier, surfaced as a debug label in captures. public required string Name { get; init; } /// The colour attachment. Required — acdream has no colour-less passes. public required GpuColorAttachment Color { get; init; } /// Depth/stencil attachment, or null for 2-D passes that need no depth. public GpuDepthAttachment? Depth { get; init; } /// Samples per pixel. Must equal of every pipeline bound inside. public int SampleCount { get; init; } = 1; /// Clears colour and depth to the standard frame-start values against the backbuffer. public static GpuPassDescription BackbufferClear(string name, Vector4 clearColor, int sampleCount) => new() { Name = name, Color = new GpuColorAttachment( Target: null, Load: GpuLoadOp.Clear, Store: sampleCount > 1 ? GpuStoreOp.Resolve : GpuStoreOp.Store, ClearColor: clearColor), Depth = new GpuDepthAttachment( Load: GpuLoadOp.Clear, Store: GpuStoreOp.DontCare, ClearDepth: 1f, ClearStencil: 0), SampleCount = sampleCount, }; }