namespace AcDream.App.Rendering.Gpu;
///
/// Records draw work inside one . Disposing the
/// encoder closes the pass.
///
/// The surface is deliberately small: it is exactly what acdream's twelve
/// renderers do, expressed the way Vulkan wants it. Everything that Vulkan bakes
/// into a pipeline (blend, depth compare, alpha-to-coverage, topology) is absent
/// here by design — those live in . Only the
/// state core Vulkan 1.3 makes dynamic is settable per draw.
///
internal interface IGpuPassEncoder : IDisposable
{
/// The pass this encoder is recording into.
GpuPassDescription Pass { get; }
/// Binds the shader program and all baked fixed state.
void BindPipeline(IGpuPipeline pipeline);
///
/// Binds a storage buffer range to a storage
/// binding. Ranges come straight from for
/// per-frame data, or from a long-lived buffer for persistent data.
///
void BindStorageBuffer(uint binding, IGpuBuffer buffer, uint offsetBytes, uint sizeBytes);
/// Binds a uniform buffer range — currently only the SceneLighting block.
void BindUniformBuffer(uint binding, IGpuBuffer buffer, uint offsetBytes, uint sizeBytes);
///
/// Binds one vertex source into of the pipeline's
/// .
///
/// Slice V6l added the binding index. Layouts written before it declare
/// exactly one interleaved vertex-rate binding 0, so every existing call site
/// passes 0; the particle pipelines add a second, per-instance binding.
///
void BindVertexBuffer(uint binding, IGpuBuffer buffer, uint offsetBytes);
/// Binds the index source.
void BindIndexBuffer(IGpuBuffer buffer, uint offsetBytes, GpuIndexType indexType);
/// Writes the shared push-constant block. Survives pipeline changes within a pass.
void SetPushConstants(in GpuPushConstants constants);
///
/// Sets the drawable rectangle. Callers always pass GL-convention coordinates
/// (origin bottom-left); the Vulkan backend converts by emitting a negative
/// viewport height, so no renderer performs a Y flip itself.
///
void SetViewport(int x, int y, int width, int height);
/// Sets the scissor rectangle in the same convention as .
void SetScissor(int x, int y, int width, int height);
/// Dynamic cull override — how the world dispatcher draws double-sided geometry.
void SetCullMode(GpuCullMode cullMode);
/// Dynamic winding override, in GL convention. The Vulkan backend applies its own inversion.
void SetFrontFace(GpuFrontFace frontFace);
/// Dynamic depth-write override — how the translucent pass stops occluding later draws.
void SetDepthWrite(bool enabled);
///
/// Dynamic stencil override: compare, the three outcome ops, reference and
/// both masks. Meaningful only inside a pipeline whose
/// is set.
///
/// Slice V6l. #117's portal punch changes every one of these between
/// its stencil-marking pass and its far-Z punch pass, and core Vulkan 1.3
/// makes all of them dynamic, so they belong here rather than in a second
/// pipeline object.
///
void SetStencil(in GpuStencilState stencil);
/// Draws indexed geometry directly, without an indirect buffer.
void DrawIndexed(uint indexCount, uint instanceCount, uint firstIndex, int vertexOffset, uint firstInstance);
/// Draws non-indexed geometry — the retained UI's batched sprite/glyph quads.
void Draw(uint vertexCount, uint instanceCount, uint firstVertex, uint firstInstance);
///
/// The production draw call: one submission covering
/// commands read from . Each command's draw index is
/// visible to the shader as gl_DrawID, offset by
/// .
///
void MultiDrawIndexedIndirect(IGpuBuffer commands, uint offsetBytes, uint drawCount, uint strideBytes);
///
/// Opens a GPU timing scope whose result becomes readable through
/// once this frame retires. Returns a
/// no-op disposable when the backend cannot measure GPU time.
///
IDisposable BeginTimerScope(string scopeName);
}