blob: 94a05bcee3b8d1560c899a743a7ed513902a0b14 [file] [edit]
export interface BeginCountRange {
begin: number;
count: number;
}
export interface BeginEndRange {
begin: number;
end: number;
}
function endOfRange(r: BeginEndRange | BeginCountRange): number {
return 'count' in r ? r.begin + r.count : r.end;
}
function* rangeAsIterator(r: BeginEndRange | BeginCountRange): Generator<number> {
for (let i = r.begin; i < endOfRange(r); ++i) {
yield i;
}
}
export class SubresourceRange {
readonly mipRange: BeginEndRange;
readonly sliceRange: BeginEndRange;
constructor(subresources: {
mipRange: BeginEndRange | BeginCountRange;
sliceRange: BeginEndRange | BeginCountRange;
}) {
this.mipRange = {
begin: subresources.mipRange.begin,
end: endOfRange(subresources.mipRange),
};
this.sliceRange = {
begin: subresources.sliceRange.begin,
end: endOfRange(subresources.sliceRange),
};
}
*each(): Generator<{ level: number; slice: number }> {
for (let level = this.mipRange.begin; level < this.mipRange.end; ++level) {
for (let slice = this.sliceRange.begin; slice < this.sliceRange.end; ++slice) {
yield { level, slice };
}
}
}
*mipLevels(): Generator<{ level: number; slices: Generator<number> }> {
for (let level = this.mipRange.begin; level < this.mipRange.end; ++level) {
yield {
level,
slices: rangeAsIterator(this.sliceRange),
};
}
}
}
export function mipSize(size: [number], level: number): [number];
export function mipSize(size: [number, number], level: number): [number, number];
export function mipSize(size: [number, number, number], level: number): [number, number, number];
export function mipSize(size: GPUExtent3DDict, level: number): GPUExtent3DDict;
export function mipSize(size: GPUExtent3D, level: number): GPUExtent3D {
const rShiftMax1 = (s: number) => Math.max(s >> level, 1);
if (size instanceof Array) {
return size.map(rShiftMax1);
} else {
return {
width: rShiftMax1(size.width),
height: rShiftMax1(size.height),
depth: rShiftMax1(size.depth),
};
}
}