namespace AcDream.App.Rendering.Gpu;
///
/// Campaign V (V0): the PINNED binding model shared by the CPU renderers, the
/// GLSL sources, and both RHI backends. Every number here appears in a shader
/// file; changing one is a contract change that must land in the same commit as
/// the matching shader edit.
///
/// The model is deliberately Vulkan-shaped and dual-legal:
///
/// set 0 — storage buffers, bindings 0..9. GLSL omits the set qualifier, and
/// GL_KHR_vulkan_glsl defines an omitted set as set 0, so one source
/// file compiles for both backends.
/// set 1 — uniform buffers. Vulkan has ONE binding namespace per set, while
/// GL keeps GL_SHADER_STORAGE_BUFFER and GL_UNIFORM_BUFFER tables
/// separate. Today mesh_modern.vert exploits that: the BatchBuffer
/// SSBO and the SceneLighting UBO both sit at binding=1. Moving UBOs
/// to their own set preserves both numbers and removes the collision.
/// set 2 — the global sampled-texture table that replaces ARB_bindless_texture.
/// Vulkan binds it as one variable-count, partially-bound,
/// update-after-bind descriptor array. GL emulates it with a storage
/// buffer of uvec2 handles at set 0 binding 9 (),
/// which is why both a set index and a storage binding exist here.
///
/// A batch no longer carries a 64-bit bindless handle; it carries a
/// index into the table. That single change is what
/// makes the CPU-side data model backend-neutral (Campaign V slice V2), and it
/// lands on GL — pixel-gated — long before any Vulkan code exists.
///
internal static class GpuBindingModel
{
// ---- set 0: storage buffers (identical numbering to today's SSBO bindings) ----
/// Per-instance transforms. std430 InstanceData { mat4 transform; }.
public const uint StorageInstances = 0;
/// Per-draw batch metadata. std430 BatchData (see ).
public const uint StorageBatches = 1;
/// Phase U.3 shared per-frame clip regions (CellClip, 144 B/slot). Slot 0 = no-clip.
public const uint StorageClipRegions = 2;
/// Phase U.3 per-instance clip-slot index, parallel to .
public const uint StorageClipSlots = 3;
/// A7 Fix B global point/spot light array.
public const uint StorageGlobalLights = 4;
/// A7 Fix B per-instance light set: 8 indices into the global light array, -1 = unused.
public const uint StorageInstanceLightSets = 5;
/// #142 per-instance indoor flag (1 = parented to an EnvCell, skip the sun).
public const uint StorageInstanceIndoor = 6;
/// #188 per-instance opacity multiplier for TransparentPartHook fades.
public const uint StorageInstanceAlpha = 7;
/// Retail SmartBox selection lighting: one vec2 (luminosity, diffuse) per instance.
public const uint StorageInstanceSelectionLighting = 8;
///
/// GL-only emulation of the Vulkan texture table: a storage buffer of uvec2
/// bindless handles indexed by . The Vulkan
/// backend binds instead and never uses this
/// binding; it is deleted with the GL backend at slice V11.
///
public const uint StorageTextureTable = 9;
/// One past the highest storage binding — the count both backends must support.
public const uint StorageBindingCount = 10;
// ---- set 1: uniform buffers ----
///
/// SceneLighting std140 block. Keeps binding=1 so the existing shader source
/// and SceneLightingUboBinding layout are untouched; the set index is
/// what disambiguates it from under Vulkan.
///
public const uint UniformSceneLighting = 1;
/// Set index carrying every uniform buffer.
public const uint UniformSet = 1;
// ---- set 2: the global texture table ----
/// Set index of the sampled-texture descriptor array (Vulkan) / logical table (GL).
public const uint TextureTableSet = 2;
/// Binding of the descriptor array within .
public const uint TextureTableBinding = 0;
///
/// Upper bound on simultaneously registered textures. Vulkan requires
/// maxDescriptorSetUpdateAfterBindSampledImages to reach this; the
/// capability probe asserts it rather than discovering it at draw time.
///
public const uint TextureTableCapacity = 16384;
// ---- push constants ----
///
/// Bytes actually written by . Vulkan guarantees
/// at least , so 32 bytes of headroom remain
/// for later slices; any growth updates this constant and the shader block in
/// the same commit.
///
public const int PushConstantBytes = 96;
/// The Vulkan-guaranteed minimum push-constant budget. A hard ceiling for us.
public const int MaxPushConstantBytes = 128;
// ---- shared layout facts the CPU writers and the shaders must agree on ----
///
/// std430 stride of BatchData. The bindless uvec2 textureHandle
/// becomes uint textureIndex plus one pad word at slice V2, so the
/// stride is unchanged and every existing CPU writer keeps its offsets.
///
public const int GpuBatchDataStrideBytes = 16;
/// Clip planes per CellClip slot; also the required gl_ClipDistance size.
public const int ClipPlanesPerSlot = 8;
/// std430 stride of one CellClip slot: 16 B header + 8 × vec4.
public const int ClipRegionStrideBytes = 16 + (ClipPlanesPerSlot * 16);
/// Lights selected per object by retail's minimize_object_lighting.
public const int MaxLightsPerObject = 8;
}