webgpuPipelineContext.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. import { IPipelineContext } from '../IPipelineContext';
  2. import { Nullable } from '../../types';
  3. import { WebGPUEngine } from '../webgpuEngine';
  4. import { InternalTexture } from '../../Materials/Textures/internalTexture';
  5. import { Effect } from '../../Materials/effect';
  6. import { WebGPUShaderProcessingContext } from './webgpuShaderProcessingContext';
  7. /** @hidden */
  8. export interface IWebGPUPipelineContextSamplerCache {
  9. textureBinding: number;
  10. samplerBinding: number;
  11. texture: InternalTexture;
  12. }
  13. /** @hidden */
  14. export interface IWebGPUPipelineContextVertexInputsCache {
  15. indexBuffer: Nullable<GPUBuffer>;
  16. indexOffset: number;
  17. vertexStartSlot: number;
  18. vertexBuffers: GPUBuffer[];
  19. vertexOffsets: number[];
  20. }
  21. /** @hidden */
  22. export class WebGPUPipelineContext implements IPipelineContext {
  23. public engine: WebGPUEngine;
  24. public availableAttributes: { [key: string]: number };
  25. public availableUBOs: { [key: string]: { setIndex: number, bindingIndex: number} };
  26. public availableSamplers: { [key: string]: number };
  27. public sources: {
  28. vertex: string
  29. fragment: string,
  30. };
  31. public stages: Nullable<GPURenderPipelineStageDescriptor>;
  32. public samplers: { [name: string]: Nullable<IWebGPUPipelineContextSamplerCache> } = { };
  33. public vertexInputs: IWebGPUPipelineContextVertexInputsCache;
  34. public bindGroupLayouts: (GPUBindGroupLayout | undefined)[];
  35. public bindGroups: GPUBindGroup[];
  36. public renderPipeline: GPURenderPipeline;
  37. // Default implementation.
  38. public onCompiled?: () => void;
  39. public get isAsync() {
  40. return false;
  41. }
  42. public get isReady(): boolean {
  43. if (this.stages) {
  44. return true;
  45. }
  46. return false;
  47. }
  48. constructor(shaderProcessingContext: WebGPUShaderProcessingContext) {
  49. this.availableAttributes = shaderProcessingContext.availableAttributes;
  50. this.availableUBOs = shaderProcessingContext.availableUBOs;
  51. }
  52. public _handlesSpectorRebuildCallback(onCompiled: (program: any) => void): void {
  53. // Nothing to do yet for spector.
  54. }
  55. public _fillEffectInformation(effect: Effect, uniformBuffersNames: { [key: string]: number }, uniformsNames: string[], uniforms: { [key: string]: Nullable<WebGLUniformLocation> }, samplerList: string[], samplers: { [key: string]: number }, attributesNames: string[], attributes: number[]) {
  56. const engine = this.engine;
  57. // TODO WEBGPU. Cleanup SEB on this entire function.
  58. let effectAvailableUniforms = engine.getUniforms(this, uniformsNames);
  59. effectAvailableUniforms.forEach((uniform, index) => {
  60. uniforms[uniformsNames[index]] = uniform;
  61. });
  62. // Prevent Memory Leak by reducing the number of string, refer to the string instead of copy.
  63. effect._fragmentSourceCode = "";
  64. effect._vertexSourceCode = "";
  65. // this._fragmentSourceCodeOverride = "";
  66. // this._vertexSourceCodeOverride = "";
  67. const foundSamplers = this.availableSamplers;
  68. let index: number;
  69. for (index = 0; index < samplerList.length; index++) {
  70. const name = samplerList[index];
  71. const sampler = foundSamplers[samplerList[index]];
  72. if (sampler == null || sampler == undefined) {
  73. samplerList.splice(index, 1);
  74. index--;
  75. }
  76. else {
  77. samplers[name] = sampler;
  78. }
  79. }
  80. attributes.push(...engine.getAttributes(this, attributesNames));
  81. }
  82. }