summaryrefslogtreecommitdiffstats
path: root/dom/webgpu/tests/cts/checkout/src/webgpu/util/texture/subresource.ts
blob: b8d6e3eb21a7d7b4e6539699c6d0264f74fd5f3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/** A range of indices expressed as `{ begin, count }`. */
export interface BeginCountRange {
  begin: number;
  count: number;
}

/* A range of indices, expressed as `{ begin, end }`. */
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;
  }
}

/**
 * Represents a range of subresources of a single-plane texture:
 * a min/max mip level and min/max array layer.
 */
export class SubresourceRange {
  readonly mipRange: BeginEndRange;
  readonly layerRange: BeginEndRange;

  constructor(subresources: {
    mipRange: BeginEndRange | BeginCountRange;
    layerRange: BeginEndRange | BeginCountRange;
  }) {
    this.mipRange = {
      begin: subresources.mipRange.begin,
      end: endOfRange(subresources.mipRange),
    };
    this.layerRange = {
      begin: subresources.layerRange.begin,
      end: endOfRange(subresources.layerRange),
    };
  }

  /**
   * Iterates over the "rectangle" of `{ level, layer }` pairs represented by the range.
   */
  *each(): Generator<{ level: number; layer: number }> {
    for (let level = this.mipRange.begin; level < this.mipRange.end; ++level) {
      for (let layer = this.layerRange.begin; layer < this.layerRange.end; ++layer) {
        yield { level, layer };
      }
    }
  }

  /**
   * Iterates over the mip levels represented by the range, each level including an iterator
   * over the array layers at that level.
   */
  *mipLevels(): Generator<{ level: number; layers: Generator<number> }> {
    for (let level = this.mipRange.begin; level < this.mipRange.end; ++level) {
      yield {
        level,
        layers: rangeAsIterator(this.layerRange),
      };
    }
  }
}