import { DEFAULT_RENDER_STATE, validateRenderState } from "./Material.js";
import {} from "./RenderDevice.js";
import {} from "./VertexFormat.js";
export class RenderPipeline {
    label;
    shader;
    vertexFormat;
    topology;
    renderState;
    disposed = false;
    requiredAttributes;
    constructor(descriptor) {
        if (descriptor.shader.disposed) {
            throw new Error("RenderPipeline shader must not be disposed.");
        }
        this.label = descriptor.label ?? descriptor.shader.label;
        this.shader = descriptor.shader;
        this.vertexFormat = descriptor.vertexFormat;
        this.topology = descriptor.topology ?? "triangles";
        this.renderState = validateRenderState({ ...DEFAULT_RENDER_STATE, ...(descriptor.renderState ?? {}) });
        this.requiredAttributes = descriptor.requiredAttributes ?? [...descriptor.shader.reflection.attributes.keys()];
        this.validateVertexFormat();
    }
    createDrawCommand(descriptor) {
        if (this.disposed) {
            throw new Error("Cannot draw with a disposed RenderPipeline.");
        }
        if (this.shader.disposed) {
            throw new Error("Cannot draw with a disposed RenderPipeline shader.");
        }
        const command = {
            label: descriptor.label ?? this.label,
            topology: this.topology,
            renderState: this.renderState,
            vertexBuffer: descriptor.vertexBuffer,
            vertexFormat: this.vertexFormat,
            vertexCount: descriptor.vertexCount,
            ...(descriptor.firstVertex !== undefined ? { firstVertex: descriptor.firstVertex } : {}),
            ...(descriptor.instanceCount !== undefined ? { instanceCount: descriptor.instanceCount } : {}),
            ...(descriptor.instanceAttributes !== undefined ? { instanceAttributes: descriptor.instanceAttributes } : {}),
            shader: this.shader,
            uniforms: descriptor.uniforms
        };
        if (descriptor.indexBuffer !== undefined) {
            Object.assign(command, {
                indexBuffer: descriptor.indexBuffer,
                indexType: descriptor.indexType,
                indexCount: descriptor.indexCount,
                ...(descriptor.firstIndex !== undefined ? { firstIndex: descriptor.firstIndex } : {})
            });
        }
        return command;
    }
    dispose() {
        this.disposed = true;
    }
    validateVertexFormat() {
        const missing = this.requiredAttributes.filter((attribute) => !this.hasVertexAttribute(attribute));
        if (missing.length > 0) {
            throw new Error(`RenderPipeline vertex format is missing required attributes: ${missing.join(", ")}`);
        }
    }
    hasVertexAttribute(attribute) {
        return this.vertexFormat.attributes.some((candidate) => candidate.semantic === attribute || candidate.shaderName === attribute);
    }
}
//# sourceMappingURL=RenderPipeline.js.map