Sebastien Vandenberghe 6 år sedan
förälder
incheckning
157cfe2c1c

+ 3 - 2
src/Engines/Extensions/engine.uniformBuffer.ts

@@ -43,8 +43,9 @@ declare module "../../Engines/thinEngine" {
          * Bind a buffer to the current webGL context at a given location
          * @param buffer defines the buffer to bind
          * @param location defines the index where to bind the buffer
+         * @param name Name of the uniform variable to bind
          */
-        bindUniformBufferBase(buffer: DataBuffer, location: number): void;
+        bindUniformBufferBase(buffer: DataBuffer, location: number, name: string): void;
 
          /**
           * Bind a specific block at a given index in a specific shader program
@@ -128,7 +129,7 @@ ThinEngine.prototype.bindUniformBuffer = function(buffer: Nullable<DataBuffer>):
     this._gl.bindBuffer(this._gl.UNIFORM_BUFFER, buffer ? buffer.underlyingResource : null);
 };
 
-ThinEngine.prototype.bindUniformBufferBase = function(buffer: DataBuffer, location: number): void {
+ThinEngine.prototype.bindUniformBufferBase = function(buffer: DataBuffer, location: number, name: string): void {
     this._gl.bindBufferBase(this._gl.UNIFORM_BUFFER, location, buffer ? buffer.underlyingResource : null);
 };
 

+ 3 - 1
src/Engines/WebGL/webGLPipelineContext.ts

@@ -66,7 +66,9 @@ export class WebGLPipelineContext implements IPipelineContext {
             samplers[name] = index;
         });
 
-        attributes.push(...engine.getAttributes(this, attributesNames));
+        for (let attr of engine.getAttributes(this, attributesNames)) {
+            attributes.push(attr);
+        }
     }
 
     /**

+ 3 - 1
src/Engines/WebGPU/webgpuPipelineContext.ts

@@ -135,7 +135,9 @@ export class WebGPUPipelineContext implements IPipelineContext {
             }
         }
 
-        attributes.push(...engine.getAttributes(this, attributesNames));
+        for (let attr of engine.getAttributes(this, attributesNames)) {
+            attributes.push(attr);
+        }
 
         // Build the uniform layout for the left over uniforms.
         this.buildUniformLayout();

+ 63 - 7
src/Engines/thinEngine.ts

@@ -3,6 +3,7 @@ import { IInternalTextureLoader } from '../Materials/Textures/internalTextureLoa
 import { Effect, IEffectCreationOptions } from '../Materials/effect';
 import { _DevTools } from '../Misc/devTools';
 import { IShaderProcessor } from './Processors/iShaderProcessor';
+import { ShaderProcessingContext } from "./Processors/shaderProcessingOptions";
 import { UniformBuffer } from '../Materials/uniformBuffer';
 import { Nullable, DataArray, IndicesArray } from '../types';
 import { EngineCapabilities } from './engineCapabilities';
@@ -171,7 +172,7 @@ export class ThinEngine {
     // Public members
 
     /** @hidden */
-    public _shaderProcessor: IShaderProcessor;
+    public _shaderProcessor: Nullable<IShaderProcessor>;
 
     /**
      * Gets or sets a boolean that indicates if textures must be forced to power of 2 size even if not required
@@ -247,7 +248,7 @@ export class ThinEngine {
     /** @hidden */
     public _badDesktopOS = false;
 
-    private _hardwareScalingLevel: number;
+    protected _hardwareScalingLevel: number;
     /** @hidden */
     public _caps: EngineCapabilities;
     private _isStencilEnable: boolean;
@@ -437,6 +438,24 @@ export class ThinEngine {
      */
     public onBeforeTextureInitObservable = new Observable<Texture>();
 
+    /** @hidden */
+    protected _isWebGPU: boolean = false;
+    /**
+     * Gets a boolean indicating if the engine runs in WebGPU or not.
+     */
+    public get isWebGPU(): boolean {
+        return this._isWebGPU;
+    }
+
+    /** @hidden */
+    protected _shaderPlatformName: string;
+    /**
+     * Gets the shader platfrom name used by the effects.
+     */
+    public get shaderPlatformName(): string {
+        return this._shaderPlatformName;
+    }
+
     /**
      * Creates a new engine
      * @param canvasOrContext defines the canvas or WebGL context to use for rendering. If you provide a WebGL context, Babylon.js will not hook events on the canvas (like pointers, keyboards, etc...) so no event observables will be available. This is mostly used when Babylon.js is used as a plugin on a system which alreay used the WebGL context
@@ -568,10 +587,12 @@ export class ThinEngine {
                     this._gl = <any>(canvas.getContext("webgl2", options) || canvas.getContext("experimental-webgl2", options));
                     if (this._gl) {
                         this._webGLVersion = 2.0;
+                        this._shaderPlatformName = "WEBGL2";
 
                         // Prevent weird browsers to lie :-)
                         if (!this._gl.deleteQuery) {
                             this._webGLVersion = 1.0;
+                            this._shaderPlatformName = "WEBGL1";
                         }
                     }
                 } catch (e) {
@@ -599,6 +620,10 @@ export class ThinEngine {
 
             if (this._gl.renderbufferStorageMultisample) {
                 this._webGLVersion = 2.0;
+                this._shaderPlatformName = "WEBGL2";
+            }
+            else {
+                this._shaderPlatformName = "WEBGL1";
             }
 
             const attributes = this._gl.getContextAttributes();
@@ -643,6 +668,35 @@ export class ThinEngine {
         console.log(`Babylon.js v${ThinEngine.Version} - ${this.description}`);
     }
 
+    /**
+     * Shared initialization across engines types.
+     * @param canvas The canvas associated with this instance of the engine.
+     * @param doNotHandleTouchAction Defines that engine should ignore modifying touch action attribute and style
+     * @param audioEngine Defines if an audio engine should be created by default
+     */
+    protected _sharedInit(canvas: HTMLCanvasElement, doNotHandleTouchAction: boolean, audioEngine: boolean) {
+        this._renderingCanvas = canvas;
+
+        // Shader processor
+        this._shaderProcessor = this._getShaderProcessor();
+    }
+
+    /**
+     * Gets a shader processor implementation fitting with the current engine type.
+     * @returns The shader processor implementation.
+     */
+    protected _getShaderProcessor(): Nullable<IShaderProcessor> {
+        if (this.webGLVersion > 1) {
+            return new WebGL2ShaderProcessor();
+        }
+        return null;
+    }
+
+    /** @hidden */
+    public _getShaderProcessingContext(): Nullable<ShaderProcessingContext> {
+        return null;
+    }
+
     private _rebuildInternalTextures(): void {
         let currentState = this._internalTexturesCache.slice(); // Do a copy because the rebuild will add proxies
 
@@ -1991,8 +2045,7 @@ export class ThinEngine {
 
             return compiledEffect;
         }
-        var effect = new Effect(baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters);
-        effect._key = name;
+        var effect = new Effect(baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, name);
         this._compiledEffects[name] = effect;
 
         return effect;
@@ -2060,9 +2113,10 @@ export class ThinEngine {
 
     /**
      * Creates a new pipeline context
+     * @param shaderProcessingContext defines the shader processing context used during the processing if available
      * @returns the new pipeline
      */
-    public createPipelineContext(): IPipelineContext {
+    public createPipelineContext(shaderProcessingContext: Nullable<ShaderProcessingContext>): IPipelineContext {
         var pipelineContext = new WebGLPipelineContext();
         pipelineContext.engine = this;
 
@@ -2157,7 +2211,8 @@ export class ThinEngine {
     public _preparePipelineContext(pipelineContext: IPipelineContext, vertexSourceCode: string, fragmentSourceCode: string, createAsRaw: boolean,
         rebuildRebind: any,
         defines: Nullable<string>,
-        transformFeedbackVaryings: Nullable<string[]>) {
+        transformFeedbackVaryings: Nullable<string[]>,
+        key: string) {
         let webGLRenderingState = pipelineContext as WebGLPipelineContext;
 
         if (createAsRaw) {
@@ -3521,8 +3576,9 @@ export class ThinEngine {
      * @param channel The texture channel
      * @param uniform The uniform to set
      * @param texture The texture to apply
+     * @param name The name of the uniform in the effect
      */
-    public setTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<BaseTexture>): void {
+    public setTexture(channel: number, uniform: Nullable<WebGLUniformLocation>, texture: Nullable<BaseTexture>, name: string): void {
         if (channel === undefined) {
             return;
         }

+ 11 - 10
src/Engines/webgpuEngine.ts

@@ -3,12 +3,14 @@ import { Nullable, DataArray, IndicesArray, FloatArray } from "../types";
 import { Scene } from "../scene";
 import { Color4 } from "../Maths/math";
 import { Scalar } from "../Maths/math.scalar";
-import { Engine, EngineCapabilities, InstancingAttributeInfo } from "../Engines/engine";
+import { Engine } from "../Engines/engine";
+import { EngineCapabilities } from "../Engines/engineCapabilities";
+import { InstancingAttributeInfo } from "../Engines/instancingAttributeInfo";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
-import { InternalTexture } from "../Materials/Textures/internalTexture";
-import { EffectCreationOptions, EffectFallbacks, Effect } from "../Materials/effect";
+import { InternalTexture, InternalTextureSource } from "../Materials/Textures/internalTexture";
+import { IEffectCreationOptions, Effect } from "../Materials/effect";
+import { EffectFallbacks } from "../Materials/effectFallbacks";
 import { _TimeToken } from "../Instrumentation/timeToken";
-import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
 import { Constants } from "./constants";
 import { WebGPUConstants } from "./WebGPU/webgpuConstants";
 import { VertexBuffer } from "../Meshes/buffer";
@@ -761,12 +763,12 @@ export class WebGPUEngine extends Engine {
     //                              Effects
     //------------------------------------------------------------------------------
 
-    public createEffect(baseName: any, attributesNamesOrOptions: string[] | EffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks,
+    public createEffect(baseName: any, attributesNamesOrOptions: string[] | IEffectCreationOptions, uniformsNamesOrEngine: string[] | Engine, samplers?: string[], defines?: string, fallbacks?: EffectFallbacks,
         onCompiled?: Nullable<(effect: Effect) => void>, onError?: Nullable<(effect: Effect, errors: string) => void>, indexParameters?: any): Effect {
         const vertex = baseName.vertexElement || baseName.vertex || baseName;
         const fragment = baseName.fragmentElement || baseName.fragment || baseName;
 
-        const name = vertex + "+" + fragment + "@" + (defines ? defines : (<EffectCreationOptions>attributesNamesOrOptions).defines);
+        const name = vertex + "+" + fragment + "@" + (defines ? defines : (<IEffectCreationOptions>attributesNamesOrOptions).defines);
         const shader = this._compiledShaders[name];
         if (shader) {
             return new Effect(baseName, attributesNamesOrOptions, uniformsNamesOrEngine, samplers, this, defines, fallbacks, onCompiled, onError, indexParameters, name, shader.sources);
@@ -1140,7 +1142,7 @@ export class WebGPUEngine extends Engine {
     }
 
     public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null, buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
-        const texture = new InternalTexture(this, InternalTexture.DATASOURCE_URL);
+        const texture = new InternalTexture(this, InternalTextureSource.Url);
         const url = String(urlArg);
 
         // TODO WEBGPU. Find a better way.
@@ -1217,7 +1219,7 @@ export class WebGPUEngine extends Engine {
     }
 
     public createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad: Nullable<(data?: any) => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format?: number, forcedExtension: any = null, createPolynomials: boolean = false, lodScale: number = 0, lodOffset: number = 0, fallback: Nullable<InternalTexture> = null, excludeLoaders: Array<IInternalTextureLoader> = []): InternalTexture {
-        var texture = fallback ? fallback : new InternalTexture(this, InternalTexture.DATASOURCE_CUBE);
+        var texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);
         texture.isCube = true;
         texture.url = rootUrl;
         texture.generateMipMaps = !noMipmap;
@@ -1393,7 +1395,7 @@ export class WebGPUEngine extends Engine {
             fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_INT;
             fullOptions.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;
         }
-        var texture = new InternalTexture(this, InternalTexture.DATASOURCE_RENDERTARGET);
+        var texture = new InternalTexture(this, InternalTextureSource.RenderTarget);
 
         var width = size.width || size;
         var height = size.height || size;
@@ -2020,7 +2022,6 @@ export class WebGPUEngine extends Engine {
                         visibility: WebGPUConstants.GPUShaderStageBit_VERTEX | WebGPUConstants.GPUShaderStageBit_FRAGMENT,
                         type: WebGPUConstants.GPUBindingType_sampler
                     });
-                    console.log(bindingDefinition.textureDimension, bindingDefinition.name);
                 }
                 else {
                     bindings.push({