import type { Disarray } from '../../data/dataTypes.ts';
import type { PrimitiveOffsetInfo } from '../../data/offsetUtils.ts';
import type { BaseData, WgslArray } from '../../data/wgslTypes.ts';
import { $internal } from '../../shared/symbols.ts';
import type { TgpuBindGroup, TgpuBindGroupLayout, TgpuLayoutEntry } from '../../tgpuBindGroupLayout.ts';
import type { IndexFlag, IndirectFlag, TgpuBuffer, VertexFlag } from '../buffer/buffer.ts';
import { RenderDrawState } from '../pipeline/drawState.ts';
import type { TgpuRenderPipeline } from '../pipeline/renderPipeline.ts';
import { type TgpuQuerySet } from '../querySet/querySet.ts';
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
import type { TgpuCommandEncoder } from './commandEncoder.ts';
import type { TgpuVertexLayout } from '../vertexLayout/vertexLayout.ts';
import { type ColorAttachment, type DepthStencilAttachment, type TgpuPassTimestampWrites } from './attachments.ts';
/**
 * The TypeGPU equivalent of {@link GPURenderPassDescriptor}. Attachment views accept
 * TypeGPU textures, texture views and canvas contexts (next to raw {@link GPUTextureView}s),
 * and query sets accept {@link TgpuQuerySet}.
 *
 * Load/store operations default to `loadOp: 'clear'`, `storeOp: 'store'`
 * (and `depthClearValue: 1` for depth attachments). For depth/stencil attachments,
 * defaults are derived from the view's format and aspect. A raw {@link GPUTextureView}
 * with no explicit operations is assumed to be depth-only; provide explicit
 * operations for raw stencil or depth-stencil views.
 */
export interface TgpuRenderPassDescriptor {
    label?: string | undefined;
    colorAttachments?: ColorAttachment | readonly (ColorAttachment | null)[] | undefined;
    depthStencilAttachment?: DepthStencilAttachment | undefined;
    occlusionQuerySet?: TgpuQuerySet<'occlusion'> | GPUQuerySet | undefined;
    timestampWrites?: TgpuPassTimestampWrites | undefined;
    maxDrawCount?: number | undefined;
}
export interface RenderPassInternals<TRaw extends GPURenderPassEncoder | GPURenderBundleEncoder = GPURenderPassEncoder | GPURenderBundleEncoder> {
    readonly rawPass: TRaw;
    readonly state: RenderDrawState;
    /** Undefined for bundle encoders and for raw pass encoders the caller owns */
    readonly owner: TgpuCommandEncoder | undefined;
    appliedVersion: number | undefined;
}
/**
 * The draw-recording surface shared by render passes and render bundle encoders,
 * mirroring {@link GPURenderCommandsMixin}.
 *
 * Draw either by binding TypeGPU pipelines to it (`pipeline.with(pass).draw(...)`),
 * or proxy-style via `pass.setPipeline(pipeline)` followed by `pass.draw(...)`.
 * Pipeline resolution is lazy: shaders compile on the first draw.
 */
export interface TgpuRenderCommands {
    readonly [$internal]: RenderPassInternals;
    readonly resourceType: 'render-pass' | 'render-bundle-encoder';
    /** Sets the current {@link TgpuRenderPipeline} for subsequent draw calls */
    setPipeline(pipeline: TgpuRenderPipeline): void;
    /** Associates a bind group with the layout it was created from */
    setBindGroup(bindGroup: TgpuBindGroup): void;
    /** Associates a bind group with the given layout */
    setBindGroup<Entries extends Record<string, TgpuLayoutEntry | null>>(bindGroupLayout: TgpuBindGroupLayout<Entries>, bindGroup: TgpuBindGroup<Entries> | GPUBindGroup): void;
    /** Binds a vertex buffer to the given vertex layout */
    setVertexBuffer<TData extends WgslArray | Disarray>(vertexLayout: TgpuVertexLayout<TData>, buffer: (TgpuBuffer<TData> & VertexFlag) | GPUBuffer, offset?: number, size?: number): void;
    /** Sets the current index buffer */
    setIndexBuffer<TData extends WgslArray | Disarray>(buffer: (TgpuBuffer<TData> & IndexFlag) | GPUBuffer, indexFormat: GPUIndexFormat, offset?: number, size?: number): void;
    draw(vertexCount: number, instanceCount?: number, firstVertex?: number, firstInstance?: number): void;
    drawIndexed(indexCount: number, instanceCount?: number, firstIndex?: number, baseVertex?: number, firstInstance?: number): void;
    /**
     * Draws primitives using parameters read from a buffer.
     * The buffer must contain 4 consecutive u32 values (vertexCount, instanceCount, firstVertex, firstInstance).
     * To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
     *
     * @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
     * @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
     */
    drawIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
    /**
     * Draws indexed primitives using parameters read from a buffer.
     * The buffer must contain 5 consecutive 32-bit integer values (indexCount u32, instanceCount u32, firstIndex u32, baseVertex i32, firstInstance u32).
     * To get the correct offset within complex data structures, use `d.memoryLayoutOf(...)`.
     *
     * @param indirectBuffer - Buffer marked with 'indirect' usage containing draw parameters or raw GPUBuffer
     * @param indirectOffset - PrimitiveOffsetInfo pointing to the first draw parameter. If not provided, starts at offset 0. To obtain safe offsets, use `d.memoryLayoutOf(...)`.
     */
    drawIndexedIndirect(indirectBuffer: (TgpuBuffer<BaseData> & IndirectFlag) | GPUBuffer, indirectOffset?: PrimitiveOffsetInfo | number): void;
}
/**
 * Records draw commands into a render bundle, mirroring {@link GPURenderBundleEncoder}.
 *
 * Call `finish()` to obtain a {@link GPURenderBundle}, replayable in a render
 * pass via {@link TgpuRenderPass.executeBundles}.
 */
export interface TgpuRenderBundleEncoder extends TgpuRenderCommands {
    readonly [$internal]: RenderPassInternals<GPURenderBundleEncoder>;
    readonly resourceType: 'render-bundle-encoder';
    /** Completes the recording and returns the resulting {@link GPURenderBundle} */
    finish(descriptor?: GPURenderBundleDescriptor): GPURenderBundle;
}
/**
 * A render pass recording into a {@link TgpuCommandEncoder}. On top of the
 * draw commands, it exposes the state that WebGPU scopes to a render pass.
 *
 * Call `end()` when done recording.
 */
export interface TgpuRenderPass extends TgpuRenderCommands {
    readonly [$internal]: RenderPassInternals<GPURenderPassEncoder>;
    readonly resourceType: 'render-pass';
    setViewport(x: number, y: number, width: number, height: number, minDepth: number, maxDepth: number): void;
    setScissorRect(x: number, y: number, width: number, height: number): void;
    setBlendConstant(color: readonly [number, number, number, number] | GPUColor): void;
    setStencilReference(reference: GPUStencilValue): void;
    beginOcclusionQuery(queryIndex: GPUSize32): void;
    endOcclusionQuery(): void;
    /**
     * Executes previously recorded {@link GPURenderBundle}s as part of this pass.
     * As per the WebGPU spec, this resets the raw pass's pipeline, bind group
     * and vertex/index buffer state. The state tracked by this typed pass is
     * re-applied on the next draw.
     */
    executeBundles(bundles: Iterable<GPURenderBundle>): void;
    /** Completes the recording of this render pass */
    end(): void;
}
export declare function INTERNAL_beginRenderPass(encoder: TgpuCommandEncoder, descriptor: TgpuRenderPassDescriptor): TgpuRenderPass;
export declare function INTERNAL_createRenderBundleEncoder(root: ExperimentalTgpuRoot, descriptor: GPURenderBundleEncoderDescriptor): TgpuRenderBundleEncoder;
export declare function INTERNAL_adoptRenderCommands(root: ExperimentalTgpuRoot, rawPass: GPURenderPassEncoder | GPURenderBundleEncoder): TgpuRenderCommands;
