/**
 * Owns the per-splat compute pass for the hybrid GSplat renderer (Pass B in the pipeline):
 *
 *   project + screen-space cull + sort key generation + compaction
 *
 * The pass reads the post-frustum-culled `compactedSplatIds` produced by
 * {@link GSplatIntervalCompaction} and writes a pre-projected raster-friendly
 * cache (see {@link CACHE_STRIDE}) plus a parallel array of depth-based sort
 * keys. A workgroup-local atomic compaction pattern (one global atomicAdd per
 * workgroup of 256 threads) keeps post-cull entries dense in the output buffers.
 *
 * Designed to live alongside the existing renderers without affecting them. The
 * cache layout is duplicated in `gsplat-projector-constants.js` (JS) and the
 * projector / hybrid VS WGSL chunks via the `{CACHE_STRIDE}` cdefine.
 *
 * @ignore
 */
export class GSplatProjector {
    /**
     * @param {GraphicsDevice} device - The graphics device (must support compute).
     */
    constructor(device: GraphicsDevice);
    /** @type {GraphicsDevice} */
    device: GraphicsDevice;
    /**
     * 32 B per splat (8 u32 slots), sized to the work-buffer capacity (not the
     * post-cull count) to avoid undersizing on transient cull-rate drops.
     *
     * @type {StorageBuffer|null}
     */
    projCache: StorageBuffer | null;
    /** @type {StorageBuffer|null} */
    sortKeys: StorageBuffer | null;
    /**
     * Single-element atomic counter; reset to 0 every frame and incremented by
     * the projector pass via per-workgroup atomicAdd.
     *
     * @type {StorageBuffer|null}
     */
    renderCounter: StorageBuffer | null;
    /**
     * Storage buffer holding interleaved bin weights {base, divider} consumed by
     * the projector for camera-relative sort key precision.
     *
     * @type {StorageBuffer|null}
     */
    binWeightsBuffer: StorageBuffer | null;
    /** @type {GSplatSortBinWeights} */
    binWeightsUtil: GSplatSortBinWeights;
    /**
     * Lazily-created projector compute variants keyed by `radial|pick|fisheye|aa`
     * combination (see `_projectorKey`). AA is mutually exclusive with pick, so up to
     * 12 variants exist; only the combinations actually needed by the running app are
     * compiled.
     *
     * @type {Map<string, Compute>}
     */
    _projectorComputes: Map<string, Compute>;
    /** @type {BindGroupFormat|null} */
    _projectorBindGroupFormat: BindGroupFormat | null;
    /**
     * Uniform buffer format for the non-fisheye projector variant.
     *
     * @type {UniformBufferFormat|null}
     */
    _projectorUniformBufferFormat: UniformBufferFormat | null;
    /**
     * Uniform buffer format for the fisheye projector variant. Adds 4 fisheye
     * scalar uniforms after the shared fields.
     *
     * @type {UniformBufferFormat|null}
     */
    _projectorUniformBufferFormatFisheye: UniformBufferFormat | null;
    /** @type {Compute|null} */
    _writeIndirectArgsCompute: Compute | null;
    /** @type {BindGroupFormat|null} */
    _writeArgsBindGroupFormat: BindGroupFormat | null;
    /** @type {UniformBufferFormat|null} */
    _writeArgsUniformBufferFormat: UniformBufferFormat | null;
    /**
     * Cached work-buffer format version; changes invalidate the projector
     * compute (its bind group format is derived from the work-buffer format).
     */
    _formatVersion: number;
    /** @type {number} */
    _allocatedCacheCount: number;
    /** @type {Float32Array} */
    cameraPositionData: Float32Array;
    /** @type {Float32Array} */
    cameraDirectionData: Float32Array;
    destroy(): void;
    /** @private */
    private _createUniformBufferFormats;
    /** @private */
    private _createWriteIndirectArgsCompute;
    /**
     * Destroys the projector compute pipelines so they are lazily rebuilt against the
     * current work-buffer format.
     *
     * @private
     */
    private _destroyProjectorComputes;
    /**
     * Builds the cache key for a projector variant combination.
     *
     * @param {boolean} radialSort - Radial vs linear sort.
     * @param {boolean} pickMode - Pick output mode.
     * @param {boolean} fisheyeMode - Fisheye projection mode.
     * @param {boolean} antiAlias - Anti-aliasing opacity compensation mode.
     * @returns {string} The cache key.
     * @private
     */
    private _projectorKey;
    /**
     * Builds the projector Compute (one variant per sort/pick/fisheye combination).
     *
     * @param {GSplatWorkBuffer} workBuffer - The current work buffer (provides format).
     * @param {boolean} radialSort - Whether to compile the RADIAL_SORT variant.
     * @param {boolean} pickMode - Whether to write pcId into the cache for picking.
     * @param {boolean} fisheyeMode - Whether to compile the GSPLAT_FISHEYE variant.
     * @param {boolean} antiAlias - Whether to compile the GSPLAT_AA variant (bakes the
     * anti-aliasing opacity compensation into the cached alpha).
     * @returns {Compute} The created compute instance.
     * @private
     */
    private _createProjectorCompute;
    /**
     * Returns the projector Compute for the requested sort/pick/fisheye combination,
     * lazily creating it. Recreates all compute instances when the work-buffer format
     * version changes.
     *
     * @param {GSplatWorkBuffer} workBuffer - The current work buffer.
     * @param {boolean} radialSort - Whether to use the radial sort variant.
     * @param {boolean} [pickMode] - Whether to use the pick-output variant.
     * @param {boolean} [fisheyeMode] - Whether to use the fisheye projection variant.
     * @param {boolean} [antiAlias] - Whether to use the anti-aliasing variant.
     * @returns {Compute} The projector compute instance.
     * @private
     */
    private _getProjectorCompute;
    /**
     * Ensures projCache and sortKeys storage buffers are sized to at least `capacity` splats.
     * Both buffers are sized to the work-buffer capacity (passed in by the caller) rather than
     * post-cull counts, mirroring `compactedSplatIds` allocation in interval compaction.
     *
     * @param {number} capacity - Required splat capacity (work-buffer total active splats).
     * @private
     */
    private _ensureCapacity;
    /**
     * Runs the project + cull + key-gen + compact compute pass.
     *
     * @param {object} params - Dispatch parameters.
     * @param {GSplatWorkBuffer} params.workBuffer - The current work buffer.
     * @param {GraphNode} params.cameraNode - The camera node (with attached CameraComponent).
     * @param {StorageBuffer} params.compactedSplatIds - Output of interval compaction.
     * @param {StorageBuffer} params.sortElementCountBuffer - GPU-written visible count from
     * interval compaction (single u32 element); the projector reads this to early-out
     * threads beyond the post-frustum-cull range.
     * @param {number} params.totalCapacity - Work-buffer capacity used to size projCache /
     * sortKeys (typically `worldState.totalActiveSplats`).
     * @param {boolean} params.radialSort - Whether to use the radial sort key variant.
     * @param {number} params.numBits - Sort key bit count (defines bucket count = 1 << numBits).
     * @param {number} params.minDist - Minimum distance for sort key normalisation.
     * @param {number} params.maxDist - Maximum distance for sort key normalisation.
     * @param {number} params.alphaClip - Alpha cull threshold.
     * @param {number} params.minPixelSize - Minimum on-screen pixel size before culling.
     * @param {number} params.minContribution - Minimum total contribution before culling.
     * @param {number} params.viewportWidth - Render viewport width in pixels.
     * @param {number} params.viewportHeight - Render viewport height in pixels.
     * @param {boolean} params.flipY - Whether the active render target uses `flipY` (must match
     * {@link Renderer#setCameraUniforms}).
     * @param {boolean} [params.pickMode] - Whether to write picking IDs into the cache.
     * @param {import('../graphics/fisheye-projection.js').FisheyeProjection} [params.fisheyeProj] -
     * Fisheye projection state. When `fisheyeProj.enabled` is true the projector picks the
     * GSPLAT_FISHEYE variant and writes NDC-style clip data; otherwise the linear path runs.
     * @param {boolean} [params.antiAlias] - Whether to bake anti-aliasing opacity
     * compensation into the cached alpha. Ignored in pick mode (picking only gates on a
     * binary opacity threshold), which keeps the projector variant count down.
     */
    dispatch(params: {
        workBuffer: GSplatWorkBuffer;
        cameraNode: GraphNode;
        compactedSplatIds: StorageBuffer;
        sortElementCountBuffer: StorageBuffer;
        totalCapacity: number;
        radialSort: boolean;
        numBits: number;
        minDist: number;
        maxDist: number;
        alphaClip: number;
        minPixelSize: number;
        minContribution: number;
        viewportWidth: number;
        viewportHeight: number;
        flipY: boolean;
        pickMode?: boolean;
        fisheyeProj?: import("../graphics/fisheye-projection.js").FisheyeProjection;
        antiAlias?: boolean;
    }): void;
    /**
     * Writes per-frame indirect draw / dispatch arguments derived from `renderCounter[0]`.
     *
     * @param {number} drawSlot - Slot index in `device.indirectDrawBuffer`.
     * @param {number} sortSlotBase - Base slot index in `device.indirectDispatchBuffer`. The
     * radix sort backend uses `sortIndirectInfo[0]` consecutive slots starting here.
     * @param {StorageBuffer} numSplatsBuffer - Storage buffer the vertex shader reads for the
     * post-cull splat count (single u32 element).
     * @param {StorageBuffer} sortElementCountBuffer - Storage buffer the radix sort reads for
     * its element count (single u32 element).
     * @param {Uint32Array} sortIndirectInfo - Sorter-owned 4-element Uint32 array returned by
     * `ComputeRadixSort.prepareIndirect()`, used as a `vec4<u32>` uniform by the shader.
     */
    writeIndirectArgs(drawSlot: number, sortSlotBase: number, numSplatsBuffer: StorageBuffer, sortElementCountBuffer: StorageBuffer, sortIndirectInfo: Uint32Array): void;
}
import type { GraphicsDevice } from '../../platform/graphics/graphics-device.js';
import { StorageBuffer } from '../../platform/graphics/storage-buffer.js';
import { GSplatSortBinWeights } from './gsplat-sort-bin-weights.js';
import { Compute } from '../../platform/graphics/compute.js';
import { BindGroupFormat } from '../../platform/graphics/bind-group-format.js';
import { UniformBufferFormat } from '../../platform/graphics/uniform-buffer-format.js';
import type { GSplatWorkBuffer } from './gsplat-work-buffer.js';
import type { GraphNode } from '../graph-node.js';
