import { native_ } from './Constants';
import { GPUCommandBuffer } from './GPUCommandBuffer';
import { GPUComputePassEncoder } from './GPUComputePassEncoder';
import { GPURenderPassEncoder } from './GPURenderPassEncoder';
export class GPUCommandEncoder {
    get label() {
        return this[native_]?.label ?? '';
    }
    static fromNative(encoder) {
        if (encoder) {
            const ret = new GPUCommandEncoder();
            ret[native_] = encoder;
            return ret;
        }
        return null;
    }
    beginComputePass(descriptor) {
        const desc = {
            label: descriptor?.label,
        };
        if (descriptor?.timestampWrites) {
            desc.timestampWrites = {
                beginningOfPassWriteIndex: descriptor.timestampWrites.beginningOfPassWriteIndex,
                endOfPassWriteIndex: descriptor.timestampWrites.endOfPassWriteIndex,
                querySet: descriptor.timestampWrites?.querySet?.[native_],
            };
        }
        return GPUComputePassEncoder.fromNative(this[native_].beginComputePass(desc));
    }
    beginRenderPass(descriptor) {
        const desc = {
            colorAttachments: new Array(descriptor?.colorAttachments?.length ?? 0),
            label: descriptor?.label,
            maxDrawCount: descriptor?.maxDrawCount,
        };
        descriptor.colorAttachments.forEach((attachment, i) => {
            const newAttachment = {
                loadOp: 'load',
                storeOp: 'store',
                view: null,
            };
            if (Array.isArray(attachment.clearValue)) {
                newAttachment.clearValue = { r: attachment.clearValue[0], g: attachment.clearValue[1], b: attachment.clearValue[2], a: attachment.clearValue[3] };
            }
            if (attachment.view) {
                newAttachment.view = attachment.view[native_];
            }
            else {
                /// ???
            }
            if (attachment.resolveTarget) {
                newAttachment.resolveTarget = attachment.resolveTarget[native_];
            }
            if (typeof attachment?.depthSlice === 'number') {
                newAttachment.depthSlice = attachment.depthSlice;
            }
            if (attachment.loadOp) {
                newAttachment.loadOp = attachment.loadOp;
            }
            if (attachment.storeOp) {
                newAttachment.storeOp = attachment.storeOp;
            }
            desc.colorAttachments[i] = newAttachment;
        });
        if (descriptor?.depthStencilAttachment) {
            desc.depthStencilAttachment = {
                depthLoadOp: descriptor.depthStencilAttachment.depthLoadOp,
                depthStoreOp: descriptor.depthStencilAttachment.depthStoreOp,
                view: descriptor.depthStencilAttachment.view?.[native_],
                depthClearValue: descriptor.depthStencilAttachment.depthClearValue,
                depthReadOnly: descriptor.depthStencilAttachment.depthReadOnly,
                stencilLoadOp: descriptor.depthStencilAttachment.stencilLoadOp,
                stencilStoreOp: descriptor.depthStencilAttachment.stencilStoreOp,
                stencilClearValue: descriptor.depthStencilAttachment.stencilClearValue,
                stencilReadOnly: descriptor.depthStencilAttachment.stencilReadOnly,
            };
        }
        if (descriptor?.occlusionQuerySet) {
            desc.occlusionQuerySet = descriptor.occlusionQuerySet[native_];
        }
        if (descriptor?.timestampWrites) {
            desc.timestampWrites = {
                beginningOfPassWriteIndex: descriptor.timestampWrites.beginningOfPassWriteIndex,
                endOfPassWriteIndex: descriptor.timestampWrites.endOfPassWriteIndex,
                querySet: descriptor.timestampWrites.querySet[native_],
            };
        }
        const passEncoder = this[native_].beginRenderPass(desc);
        return GPURenderPassEncoder.fromNative(passEncoder);
    }
    clearBuffer(buffer, offset, size) {
        this[native_].clearBuffer(buffer[native_], offset ?? -1, size ?? -1);
    }
    copyBufferToBuffer(source, sourceOffset, destination, destinationOffset, size) {
        this[native_].copyBufferToBuffer(source[native_], sourceOffset, destination[native_], destinationOffset, size);
    }
    copyBufferToTexture(source, destination, copySize) {
        const src = {
            buffer: source.buffer[native_],
            bytesPerRow: source.bytesPerRow,
        };
        if (typeof source.offset === 'number') {
            src.offset = source.offset;
        }
        if (typeof source.rowsPerImage === 'number') {
            src.rowsPerImage = source.rowsPerImage;
        }
        const dst = {
            texture: destination.texture[native_],
        };
        if (destination.aspect) {
            dst.aspect = destination.aspect;
        }
        if (typeof destination.mipLevel === 'number') {
            dst.mipLevel = destination.mipLevel;
        }
        if (destination.origin) {
            dst.origin = destination.origin;
        }
        let size;
        if (Array.isArray(copySize)) {
            size = {
                width: copySize[0],
                height: copySize[1] ?? 1,
                depthOrArrayLayers: copySize[2] ?? 1,
            };
        }
        else {
            size = { ...copySize };
        }
        this[native_].copyBufferToTexture(src, dst, size);
    }
    copyTextureToBuffer(source, destination, copySize) {
        const src = {
            texture: source.texture[native_],
        };
        if (source.aspect) {
            src.aspect = source.aspect;
        }
        if (typeof source.mipLevel === 'number') {
            src.mipLevel = source.mipLevel;
        }
        if (source.origin) {
            src.origin = source.origin;
        }
        const dst = {
            buffer: destination.buffer[native_],
            bytesPerRow: destination.bytesPerRow,
        };
        if (typeof destination.offset === 'number') {
            dst.offset = destination.offset;
        }
        if (typeof destination.rowsPerImage === 'number') {
            dst.rowsPerImage = destination.rowsPerImage;
        }
        let size;
        if (Array.isArray(copySize)) {
            size = {
                width: copySize[0],
                height: copySize[1] ?? 1,
                depthOrArrayLayers: copySize[2] ?? 1,
            };
        }
        else {
            size = { ...copySize };
        }
        this[native_].copyTextureToBuffer(src, dst, size);
    }
    copyTextureToTexture(source, destination, copySize) {
        const src = {
            texture: source.texture[native_],
        };
        if (source.aspect) {
            src.aspect = source.aspect;
        }
        if (typeof source.mipLevel === 'number') {
            src.mipLevel = source.mipLevel;
        }
        if (source.origin) {
            src.origin = source.origin;
        }
        const dst = {
            texture: destination.texture[native_],
        };
        if (destination.aspect) {
            dst.aspect = destination.aspect;
        }
        if (typeof destination.mipLevel === 'number') {
            dst.mipLevel = destination.mipLevel;
        }
        if (destination.origin) {
            dst.origin = destination.origin;
        }
        let size;
        if (Array.isArray(copySize)) {
            size = {
                width: copySize[0],
                height: copySize[1] ?? 1,
                depthOrArrayLayers: copySize[2] ?? 1,
            };
        }
        else {
            size = { ...copySize };
        }
        this[native_].copyTextureToTexture(src, dst, size);
    }
    finish(descriptor) {
        const ret = this[native_].finish(descriptor);
        return GPUCommandBuffer.fromNative(ret);
    }
    insertDebugMarker(markerLabel) {
        this[native_].insertDebugMarker(markerLabel);
    }
    popDebugGroup() {
        this[native_].popDebugGroup();
    }
    pushDebugGroup(groupLabel) {
        this[native_].pushDebugGroup(groupLabel);
    }
    resolveQuerySet(querySet, firstQuery, queryCount, destination, destinationOffset) {
        this[native_].resolveQuerySet(querySet[native_], firstQuery, queryCount, destination[native_], destinationOffset);
    }
    writeTimestamp(querySet, queryIndex) {
        this[native_].writeTimestamp(querySet[native_], queryIndex);
    }
}
//# sourceMappingURL=GPUCommandEncoder.js.map