webgpuCacheRenderPipelineTree.ts 2.2 KB

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