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