The transitional path for slices V4a-V4g needs no special API after all. On GL, BeginPass binds the target framebuffer and applies load ops but deliberately leaves viewport and scissor to the encoder, so a renderer being ported mid-campaign opens a Load/Store pass against the backbuffer and gets exactly today's behavior while the frame spine still owns clears. One less contract concept, and one less thing for V4h to unwind. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
85 lines
3.8 KiB
C#
85 lines
3.8 KiB
C#
using System.Numerics;
|
|
|
|
namespace AcDream.App.Rendering.Gpu;
|
|
|
|
/// <summary>
|
|
/// The colour attachment for a pass.
|
|
/// </summary>
|
|
/// <param name="Target">
|
|
/// 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
|
|
/// <paramref name="Store"/> is <see cref="GpuStoreOp.Resolve"/>).
|
|
/// </param>
|
|
/// <param name="Load">What happens to existing contents on entry.</param>
|
|
/// <param name="Store">What happens to contents on exit.</param>
|
|
/// <param name="ClearColor">Clear value used when <paramref name="Load"/> is <see cref="GpuLoadOp.Clear"/>.</param>
|
|
internal readonly record struct GpuColorAttachment(
|
|
IGpuRenderTarget? Target,
|
|
GpuLoadOp Load,
|
|
GpuStoreOp Store,
|
|
Vector4 ClearColor);
|
|
|
|
/// <summary>
|
|
/// The depth/stencil attachment for a pass. Depth is transient in every acdream
|
|
/// pass — nothing reads it after the frame — so <see cref="Store"/> is normally
|
|
/// <see cref="GpuStoreOp.DontCare"/>, which lets Vulkan skip writing it back to
|
|
/// memory entirely.
|
|
/// </summary>
|
|
/// <param name="Load">What happens to existing contents on entry.</param>
|
|
/// <param name="Store">What happens to contents on exit.</param>
|
|
/// <param name="ClearDepth">Depth clear value. acdream renders with NDC z in [0,1], so far = 1.</param>
|
|
/// <param name="ClearStencil">Stencil clear value; #117's portal punch uses the stencil aspect.</param>
|
|
internal readonly record struct GpuDepthAttachment(
|
|
GpuLoadOp Load,
|
|
GpuStoreOp Store,
|
|
float ClearDepth,
|
|
uint ClearStencil);
|
|
|
|
/// <summary>
|
|
/// 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, <c>BeginPass</c> 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
|
|
/// <see cref="GpuLoadOp.Load"/> / <see cref="GpuStoreOp.Store"/> 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.
|
|
/// </summary>
|
|
internal sealed record GpuPassDescription
|
|
{
|
|
/// <summary>Stable identifier, surfaced as a debug label in captures.</summary>
|
|
public required string Name { get; init; }
|
|
|
|
/// <summary>The colour attachment. Required — acdream has no colour-less passes.</summary>
|
|
public required GpuColorAttachment Color { get; init; }
|
|
|
|
/// <summary>Depth/stencil attachment, or null for 2-D passes that need no depth.</summary>
|
|
public GpuDepthAttachment? Depth { get; init; }
|
|
|
|
/// <summary>Samples per pixel. Must equal <see cref="GpuPipelineDescription.SampleCount"/> of every pipeline bound inside.</summary>
|
|
public int SampleCount { get; init; } = 1;
|
|
|
|
/// <summary>Clears colour and depth to the standard frame-start values against the backbuffer.</summary>
|
|
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,
|
|
};
|
|
}
|