Bläddra i källkod

Merge pull request #9526 from Popov72/webgpu-create-engine

Helper class to create engine instances
David Catuhe 4 år sedan
förälder
incheckning
6cfc968351
4 ändrade filer med 60 tillägg och 4 borttagningar
  1. 29 0
      src/Engines/engineFactory.ts
  2. 1 0
      src/Engines/index.ts
  3. 9 2
      src/Engines/thinEngine.ts
  4. 21 2
      src/Engines/webgpuEngine.ts

+ 29 - 0
src/Engines/engineFactory.ts

@@ -0,0 +1,29 @@
+import { Engine } from "./engine";
+import { NullEngine } from "./nullEngine";
+import { ThinEngine } from "./thinEngine";
+import { WebGPUEngine } from "./webgpuEngine";
+
+/**
+ * Helper class to create the best engine depending on the current hardware
+ */
+export class EngineFactory {
+
+    /**
+     * Creates an engine based on the capabilities of the underlying hardware
+     * @param canvas Defines the canvas to use to display the result
+     * @param options Defines the options passed to the engine to create the context dependencies
+     * @returns a promise that resolves with the created engine
+     */
+    public static CreateAsync(canvas: HTMLCanvasElement, options: any): Promise<ThinEngine> {
+        if (WebGPUEngine.IsSupported) {
+            return WebGPUEngine.CreateAsync(canvas, options);
+        } else if (Engine.IsSupported) {
+            return new Promise((resolve) => {
+                resolve(new Engine(canvas, undefined, options));
+            });
+        }
+        return new Promise((resolve) => {
+            resolve(new NullEngine(options));
+        });
+    }
+}

+ 1 - 0
src/Engines/index.ts

@@ -15,3 +15,4 @@ export * from "./nativeEngine";
 export * from "./Processors/shaderCodeInliner";
 export * from "./performanceConfigurator";
 export * from "./engineFeatures";
+export * from "./engineFactory";

+ 9 - 2
src/Engines/thinEngine.ts

@@ -136,6 +136,11 @@ export interface EngineOptions extends WebGLContextAttributes {
      * Will prevent the system from falling back to software implementation if a hardware device cannot be created
      */
     failIfMajorPerformanceCaveat?: boolean;
+
+    /**
+     * Defines whether to adapt to the device's viewport characteristics (default: false)
+     */
+    adaptToDeviceRatio?: boolean;
 }
 
 /**
@@ -549,7 +554,7 @@ export class ThinEngine {
      * @param options defines further options to be sent to the getContext() function
      * @param adaptToDeviceRatio defines whether to adapt to the device's viewport characteristics (default: false)
      */
-    constructor(canvasOrContext: Nullable<HTMLCanvasElement | OffscreenCanvas | WebGLRenderingContext | WebGL2RenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio: boolean = false) {
+    constructor(canvasOrContext: Nullable<HTMLCanvasElement | OffscreenCanvas | WebGLRenderingContext | WebGL2RenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio?: boolean) {
 
         let canvas: Nullable<HTMLCanvasElement> = null;
 
@@ -561,11 +566,13 @@ export class ThinEngine {
             return;
         }
 
+        adaptToDeviceRatio = adaptToDeviceRatio ?? options.adaptToDeviceRatio ?? false;
+
         if ((canvasOrContext as any).getContext) {
             canvas = <HTMLCanvasElement>canvasOrContext;
             this._renderingCanvas = canvas;
 
-            if (antialias != null) {
+            if (antialias !== undefined) {
                 options.antialias = antialias;
             }
 

+ 21 - 2
src/Engines/webgpuEngine.ts

@@ -131,6 +131,11 @@ export interface WebGPUEngineOptions extends GPURequestAdapterOptions {
      * Defines wether we should generate debug markers in the gpu command lists (can be seen with PIX for eg)
      */
     enableGPUDebugMarkers?: boolean;
+
+    /**
+     * Options to load the associated Glslang library
+     */
+    glslangOptions?: GlslangOptions;
 }
 
 /**
@@ -277,6 +282,20 @@ export class WebGPUEngine extends Engine {
     }
 
     /**
+     * Create a new instance of the gpu engine asynchronously
+     * @param canvas Defines the canvas to use to display the result
+     * @param options Defines the options passed to the engine to create the GPU context dependencies
+     * @returns a promise that resolves with the created engine
+     */
+    public static CreateAsync(canvas: HTMLCanvasElement, options: WebGPUEngineOptions = {}): Promise<WebGPUEngine> {
+        const engine = new WebGPUEngine(canvas, options);
+
+        return new Promise((resolve) => {
+            engine.initAsync(options.glslangOptions).then(() => resolve(engine));
+        });
+    }
+
+    /**
      * Create a new instance of the gpu engine.
      * @param canvas Defines the canvas to use to display the result
      * @param options Defines the options passed to the engine to create the GPU context dependencies
@@ -345,7 +364,7 @@ export class WebGPUEngine extends Engine {
      * @returns a promise notifying the readiness of the engine.
      */
     public initAsync(glslangOptions?: GlslangOptions): Promise<void> {
-        return this._initGlslang(glslangOptions)
+        return this._initGlslang(glslangOptions ?? this._options?.glslangOptions)
             .then((glslang: any) => {
                 this._glslang = glslang;
                 return navigator.gpu!.requestAdapter(this._options);
@@ -492,7 +511,7 @@ export class WebGPUEngine extends Engine {
             supportRenderAndCopyToLodForFloatTextures: true,
             supportDepthStencilTexture: true,
             supportShadowSamplers: true,
-            uniformBufferHardCheckMatrix: true,
+            uniformBufferHardCheckMatrix: false,
             allowTexturePrefiltering: true,
             trackUbosInFrame: true,
             supportCSM: true,