import { type TextureSchemaForDescriptor, type WgslStorageTexture, type WgslTexture } from '../../data/texture.ts';
import type { StorageFlag } from '../../extension.ts';
import { type ResolvedSnippet } from '../../data/snippet.ts';
import type { F32, Vec4f, Vec4i, Vec4u } from '../../data/wgslTypes.ts';
import type { TgpuNamable } from '../../shared/meta.ts';
import type { Infer, ValidateTextureViewSchema } from '../../shared/repr.ts';
import { type TextureFormats, type ViewDimensionToDimension } from './textureFormats.ts';
import type { TgpuDeviceOwningSoul, TgpuSoul } from '../../shared/soul.ts';
import { $gpuValueOf, $internal, $repr, $resolve, $soul } from '../../shared/symbols.ts';
import type { Default, TypedArray, UnionToIntersection } from '../../shared/utilityTypes.ts';
import type { LayoutMembership } from '../../tgpuBindGroupLayout.ts';
import type { ResolutionCtx, SelfResolvable } from '../../types.ts';
import type { ExperimentalTgpuRoot } from '../root/rootTypes.ts';
import type { TextureProps } from './textureProps.ts';
import type { AllowedUsages, LiteralToExtensionMap, RenderFlag, SampledFlag } from './usageExtension.ts';
export type TextureInternals = {
    root: ExperimentalTgpuRoot;
    materialize(): GPUTexture;
};
export type TextureUsageLiteral = 'sampled' | 'storage' | 'render' | 'transient';
export interface TgpuTextureSoul<TProps extends TextureProps = TextureProps> extends TgpuDeviceOwningSoul<'texture', GPUTexture> {
    readonly props: TProps;
    flags: GPUTextureUsageFlags;
    flagsOverridden: boolean;
    readonly usages: TextureUsageLiteral[];
}
export interface TgpuTextureViewSoul<T extends WgslTexture | WgslStorageTexture | 'render' = WgslTexture | WgslStorageTexture | 'render'> extends TgpuSoul<'texture-view'> {
    readonly texture: TgpuTexture;
    readonly schema: T;
    readonly descriptor: (TgpuTextureViewDescriptor & {
        sampleType?: T extends WgslTexture ? 'float' | 'unfilterable-float' : never;
    }) | undefined;
    raw?: GPUTextureView | undefined;
}
type TextureViewInternals = {
    readonly unwrap: (() => GPUTextureView) | undefined;
    readonly format?: GPUTextureFormat | undefined;
    readonly aspect?: GPUTextureAspect | undefined;
};
export type TexelData = Vec4u | Vec4i | Vec4f;
export type ExternalImageSource = HTMLCanvasElement | HTMLImageElement | HTMLVideoElement | ImageBitmap | ImageData | OffscreenCanvas | VideoFrame;
export type TextureWriteFit = 'stretch';
export type TextureWriteOptions = {
    /**
     * How to handle a source whose dimensions do not match the texture.
     *
     * By default, mismatched writes throw. Use `'stretch'` to resample the
     * source to the texture's dimensions.
     */
    fit?: TextureWriteFit;
};
type TgpuTextureViewDescriptor = {
    /**
     * Which {@link GPUTextureAspect | aspect(s)} of the texture are accessible to the texture view.
     */
    aspect?: GPUTextureAspect;
    /**
     * The first (most detailed) mipmap level accessible to the texture view.
     */
    baseMipLevel?: GPUIntegerCoordinate;
    /**
     * How many mipmap levels, starting with {@link GPUTextureViewDescriptor#baseMipLevel}, are accessible to
     * the texture view.
     */
    mipLevelCount?: GPUIntegerCoordinate;
    /**
     * The index of the first array layer accessible to the texture view.
     */
    baseArrayLayer?: GPUIntegerCoordinate;
    /**
     * How many array layers, starting with {@link GPUTextureViewDescriptor#baseArrayLayer}, are accessible
     * to the texture view.
     */
    arrayLayerCount?: GPUIntegerCoordinate;
    /**
     * The format of the texture view. Must be either the {@link GPUTextureDescriptor#format} of the
     * texture or one of the {@link GPUTextureDescriptor#viewFormats} specified during its creation.
     */
    format?: GPUTextureFormat;
};
type DefaultViewSchema<T extends Partial<TextureProps>> = TextureSchemaForDescriptor<{
    dimension: Default<T['dimension'], '2d'>;
    sampleType: T['format'] extends keyof TextureFormats ? TextureFormats[T['format']]['channelType'] : TextureFormats[keyof TextureFormats]['channelType'];
    multisampled: Default<T['sampleCount'], 1> extends 1 ? false : true;
}>;
type BaseDimension<T extends string> = T extends keyof ViewDimensionToDimension ? ViewDimensionToDimension[T] : never;
type OptionalDimension<T extends string> = T extends '2d' | '2d-array' | 'cube' | 'cube-array' ? {
    dimension?: BaseDimension<T>;
} : {
    dimension: BaseDimension<T>;
};
type MultisampledProps<T extends WgslTexture> = T['multisampled'] extends true ? OptionalDimension<T['dimension']> & {
    sampleCount: 4;
} : OptionalDimension<T['dimension']> & {
    sampleCount?: 1;
};
export type PropsForSchema<T extends WgslTexture | WgslStorageTexture> = T extends WgslTexture ? {
    size: readonly number[];
    format: GPUTextureFormat;
} & MultisampledProps<T> : T extends WgslStorageTexture ? {
    size: readonly number[];
    format: T['format'];
} & OptionalDimension<T['dimension']> : never;
type CopyCompatibleTexture<T extends TextureProps> = TgpuTexture<{
    size: T['size'];
    format: T['format'];
    sampleCount?: T['sampleCount'];
}>;
export interface TgpuTexture<TProps extends TextureProps = any> extends TgpuNamable {
    readonly [$internal]: TextureInternals;
    readonly [$soul]: TgpuTextureSoul<TProps>;
    readonly resourceType: 'texture';
    readonly props: TProps;
    readonly destroyed: boolean;
    readonly usableAsStorage: boolean;
    readonly usableAsSampled: boolean;
    readonly usableAsRender: boolean;
    $usage<T extends AllowedUsages<TProps>[]>(...usages: T): this & UnionToIntersection<LiteralToExtensionMap[T[number]]>;
    $overrideFlags(flags: GPUTextureUsageFlags): this & StorageFlag & SampledFlag & RenderFlag;
    createView(...args: this['usableAsSampled'] extends true ? [] : [ValidateTextureViewSchema<this, WgslTexture>]): TgpuTextureView<DefaultViewSchema<TProps>>;
    createView(schema: 'render', viewDescriptor?: TgpuTextureViewDescriptor): TgpuTextureRenderView;
    createView<T extends WgslTexture>(schema: ValidateTextureViewSchema<this, T>, viewDescriptor?: TgpuTextureViewDescriptor & {
        sampleType?: T['sampleType'] extends F32 ? 'float' | 'unfilterable-float' : never;
    }): TgpuTextureView<T>;
    createView<T extends WgslStorageTexture>(schema: ValidateTextureViewSchema<this, T>, viewDescriptor?: TgpuTextureViewDescriptor): TgpuTextureView<T>;
    clear(mipLevel?: number | 'all'): void;
    generateMipmaps(baseMipLevel?: number, mipLevels?: number): void;
    write(source: ExternalImageSource | ExternalImageSource[], options?: TextureWriteOptions): void;
    write(source: ArrayBuffer | TypedArray | DataView, mipLevel?: number): void;
    copyFrom<T extends CopyCompatibleTexture<TProps>>(source: T): void;
    destroy(): void;
}
export interface TgpuTextureView<TSchema extends WgslStorageTexture | WgslTexture = WgslStorageTexture | WgslTexture> extends TgpuNamable {
    readonly [$internal]: TextureViewInternals;
    readonly resourceType: 'texture-view';
    readonly schema: TSchema;
    readonly size?: number[] | undefined;
    readonly [$gpuValueOf]: Infer<TSchema>;
    $: Infer<TSchema>;
    toString(): string;
}
export interface TgpuTextureRenderView {
    readonly [$internal]: TextureViewInternals;
    readonly resourceType: 'texture-view';
    readonly descriptor: TgpuTextureViewDescriptor;
}
export declare function INTERNAL_createTexture(props: TextureProps, root: ExperimentalTgpuRoot, rawTexture?: GPUTexture): TgpuTexture<TextureProps>;
export declare function isTexture(value: unknown): value is TgpuTexture;
export declare function isTextureView(value: unknown): value is TgpuTextureView;
export declare class TgpuLaidOutTextureViewImpl<T extends WgslTexture | WgslStorageTexture> implements TgpuTextureView<T>, SelfResolvable {
    #private;
    /** Type-token, not available at runtime */
    readonly [$repr]: Infer<T>;
    readonly [$internal]: {
        unwrap: undefined;
    };
    readonly resourceType: "texture-view";
    readonly schema: T;
    constructor(schema: T, membership: LayoutMembership);
    toString(): string;
    [$resolve](ctx: ResolutionCtx): ResolvedSnippet;
    get [$gpuValueOf](): Infer<T>;
    get $(): Infer<T>;
    $name(label: string): this;
}
export declare class TgpuTextureRenderViewImpl implements TgpuTextureRenderView {
    readonly [$internal]: TextureViewInternals;
    readonly [$soul]: TgpuTextureViewSoul<'render'>;
    readonly resourceType: "texture-view";
    constructor(baseTexture: TgpuTexture, descriptor?: TgpuTextureViewDescriptor);
    get descriptor(): TgpuTextureViewDescriptor;
}
export {};
