webgpuCacheRenderPipelineTree.ts 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { VertexBuffer } from "../../Meshes/buffer";
  2. import { Nullable } from "../../types";
  3. import { WebGPUCacheRenderPipeline } from "./webgpuCacheRenderPipeline";
  4. /** @hidden */
  5. class NodeState {
  6. public values: { [name: number]: NodeState };
  7. public pipeline: GPURenderPipeline;
  8. constructor() {
  9. this.values = {};
  10. }
  11. public count(): [number, number] {
  12. let countNode = 0, countPipeline = this.pipeline ? 1 : 0;
  13. for (const value in this.values) {
  14. const node = this.values[value];
  15. const [childCountNodes, childCoundPipeline] = node!.count();
  16. countNode += childCountNodes;
  17. countPipeline += childCoundPipeline;
  18. countNode++;
  19. }
  20. return [countNode, countPipeline];
  21. }
  22. }
  23. /** @hidden */
  24. export class WebGPUCacheRenderPipelineTree extends WebGPUCacheRenderPipeline {
  25. private static _Cache: NodeState = new NodeState();
  26. private _nodeStack: NodeState[];
  27. public static GetNodeCounts(): { nodeCount: number, pipelineCount: number } {
  28. const counts = WebGPUCacheRenderPipelineTree._Cache.count();
  29. return { nodeCount: counts[0], pipelineCount: counts[1] };
  30. }
  31. constructor(device: GPUDevice, emptyVertexBuffer: VertexBuffer) {
  32. super(device, emptyVertexBuffer);
  33. this._nodeStack = [];
  34. this._nodeStack[0] = WebGPUCacheRenderPipelineTree._Cache;
  35. }
  36. protected _getRenderPipeline(param: { token: any, pipeline: Nullable<GPURenderPipeline> }): void {
  37. let node = this._nodeStack[this._stateDirtyLowestIndex];
  38. for (let i = this._stateDirtyLowestIndex; i < this._states.length; ++i) {
  39. let nn: NodeState | undefined = node!.values[this._states[i]];
  40. if (!nn) {
  41. nn = new NodeState();
  42. node!.values[this._states[i]] = nn;
  43. }
  44. node = nn;
  45. this._nodeStack[i + 1] = node;
  46. }
  47. param.token = node;
  48. param.pipeline = node.pipeline;
  49. }
  50. protected _setRenderPipeline(param: { token: NodeState, pipeline: Nullable<GPURenderPipeline> }): void {
  51. param.token.pipeline = param.pipeline!;
  52. }
  53. }