Popov72 4 лет назад
Родитель
Сommit
4df32485ae

+ 1 - 1
localDev/index.html

@@ -91,7 +91,7 @@
                     if (typeof createEngine !== "undefined") {
                         engine = createEngine();
                     } else {
-                        engine = new BABYLON.Engine(canvas, false, { premultipliedAlpha: false, stencil: true, disableWebGL2Support: false, preserveDrawingBuffer: true });
+                        engine = new BABYLON.Engine(canvas, true, { premultipliedAlpha: false, stencil: true, disableWebGL2Support: false, preserveDrawingBuffer: true });
                     }
 
                     engine.getCaps().textureAnisotropicFilterExtension = false;

+ 17 - 0
src/Engines/WebGPU/webgpuHardwareTexture.ts

@@ -8,16 +8,27 @@ import { WebGPUTextureHelper } from './webgpuTextureHelper';
 export class WebGPUHardwareTexture implements HardwareTextureWrapper {
 
     private _webgpuTexture: Nullable<GPUTexture>;
+    private _webgpuMSAATexture: Nullable<GPUTexture>;
 
     public get underlyingResource(): Nullable<GPUTexture> {
         return this._webgpuTexture;
     }
 
+    public get msaaTexture(): Nullable<GPUTexture> {
+        return this._webgpuMSAATexture;
+    }
+
+    public set msaaTexture(texture: Nullable<GPUTexture>) {
+        this._webgpuMSAATexture = texture;
+    }
+
     public view: Nullable<GPUTextureView>;
     public format: GPUTextureFormat = WebGPUConstants.TextureFormat.RGBA8Unorm;
+    public textureUsages = 0;
 
     constructor(existingTexture: Nullable<GPUTexture> = null) {
         this._webgpuTexture = existingTexture;
+        this._webgpuMSAATexture = null;
         this.view = null;
     }
 
@@ -25,6 +36,10 @@ export class WebGPUHardwareTexture implements HardwareTextureWrapper {
         this._webgpuTexture = hardwareTexture;
     }
 
+    public setMSAATexture(hardwareTexture: GPUTexture): void {
+        this._webgpuMSAATexture = hardwareTexture;
+    }
+
     public setUsage(textureSource: number, generateMipMaps: boolean, isCube: boolean, width: number, height: number): void {
         generateMipMaps = textureSource === InternalTextureSource.RenderTarget ? false : generateMipMaps;
 
@@ -43,11 +58,13 @@ export class WebGPUHardwareTexture implements HardwareTextureWrapper {
 
     public reset(): void {
         this._webgpuTexture = null;
+        this._webgpuMSAATexture = null;
         this.view = null;
     }
 
     public release(): void {
         this._webgpuTexture?.destroy();
+        this._webgpuMSAATexture?.destroy();
         this.reset();
     }
 }

+ 48 - 14
src/Engines/WebGPU/webgpuTextureHelper.ts

@@ -388,6 +388,10 @@ export class WebGPUTextureHelper {
         return !!(texture as HardwareTextureWrapper).release;
     }
 
+    private _isInternalTexture(texture: InternalTexture | GPUTexture): texture is InternalTexture {
+        return !!(texture as InternalTexture).dispose;
+    }
+
     public isImageBitmap(imageBitmap: ImageBitmap | { width: number, height: number }): imageBitmap is ImageBitmap {
         return (imageBitmap as ImageBitmap).close !== undefined;
     }
@@ -817,10 +821,6 @@ export class WebGPUTextureHelper {
         }
     }
 
-    //------------------------------------------------------------------------------
-    //                                  Update
-    //------------------------------------------------------------------------------
-
     public createGPUTextureForInternalTexture(texture: InternalTexture, width?: number, height?: number, depth?: number): WebGPUHardwareTexture {
         if (!texture._hardwareTexture) {
             texture._hardwareTexture = new WebGPUHardwareTexture();
@@ -840,7 +840,7 @@ export class WebGPUTextureHelper {
 
         gpuTextureWrapper.format = this.getWebGPUTextureFormat(texture.type, texture.format);
 
-        const textureUsages =
+        gpuTextureWrapper.textureUsages =
             texture._source === InternalTextureSource.RenderTarget ? WebGPUConstants.TextureUsage.Sampled | WebGPUConstants.TextureUsage.CopySrc | WebGPUConstants.TextureUsage.OutputAttachment :
             texture._source === InternalTextureSource.Depth ? WebGPUConstants.TextureUsage.Sampled | WebGPUConstants.TextureUsage.OutputAttachment : -1;
 
@@ -848,8 +848,7 @@ export class WebGPUTextureHelper {
         const layerCount = depth || 1;
 
         if (texture.isCube) {
-            // TODO WEBGPU handle depth for cube textures?
-            const gpuTexture = this.createCubeTexture({ width, height }, texture.generateMipMaps, texture.generateMipMaps, texture.invertY, false, gpuTextureWrapper.format, texture.samples || 1, this._commandEncoderForCreation, textureUsages);
+            const gpuTexture = this.createCubeTexture({ width, height }, texture.generateMipMaps, texture.generateMipMaps, texture.invertY, false, gpuTextureWrapper.format, 1, this._commandEncoderForCreation, gpuTextureWrapper.textureUsages);
 
             gpuTextureWrapper.set(gpuTexture);
             gpuTextureWrapper.createView({
@@ -860,7 +859,7 @@ export class WebGPUTextureHelper {
                 aspect: WebGPUConstants.TextureAspect.All
             });
         } else {
-            const gpuTexture = this.createTexture({ width, height, layers: layerCount }, texture.generateMipMaps, texture.generateMipMaps, texture.invertY, false, texture.is3D, gpuTextureWrapper.format, texture.samples || 1, this._commandEncoderForCreation, textureUsages);
+            const gpuTexture = this.createTexture({ width, height, layers: layerCount }, texture.generateMipMaps, texture.generateMipMaps, texture.invertY, false, texture.is3D, gpuTextureWrapper.format, 1, this._commandEncoderForCreation, gpuTextureWrapper.textureUsages);
 
             gpuTextureWrapper.set(gpuTexture);
             gpuTextureWrapper.createView({
@@ -877,9 +876,40 @@ export class WebGPUTextureHelper {
         texture.height = texture.baseHeight = height;
         texture.depth = texture.baseDepth = depth;
 
+        this.createMSAATexture(texture, texture.samples);
+
         return gpuTextureWrapper;
     }
 
+    public createMSAATexture(texture: InternalTexture, samples: number): void {
+        const gpuTextureWrapper = texture._hardwareTexture as Nullable<WebGPUHardwareTexture>;
+
+        if (gpuTextureWrapper?.msaaTexture) {
+            this.releaseTexture(gpuTextureWrapper.msaaTexture);
+            gpuTextureWrapper.msaaTexture = null;
+        }
+
+        if (!gpuTextureWrapper || (samples ?? 1) <= 1) {
+            return;
+        }
+
+        const width = texture.width;
+        const height = texture.height;
+        const layerCount = texture.depth || 1;
+
+        if (texture.isCube) {
+            const gpuMSAATexture = this.createCubeTexture({ width, height }, false, false, texture.invertY, false, gpuTextureWrapper.format, samples, this._commandEncoderForCreation, gpuTextureWrapper.textureUsages);
+            gpuTextureWrapper.setMSAATexture(gpuMSAATexture);
+        } else {
+            const gpuMSAATexture = this.createTexture({ width, height, layers: layerCount }, false, false, texture.invertY, false, texture.is3D, gpuTextureWrapper.format, samples, this._commandEncoderForCreation, gpuTextureWrapper.textureUsages);
+            gpuTextureWrapper.setMSAATexture(gpuMSAATexture);
+        }
+    }
+
+    //------------------------------------------------------------------------------
+    //                                  Update
+    //------------------------------------------------------------------------------
+
     public updateCubeTextures(imageBitmaps: ImageBitmap[] | Uint8Array[], gpuTexture: GPUTexture, width: number, height: number, format: GPUTextureFormat, invertY = false, premultiplyAlpha = false, offsetX = 0, offsetY = 0,
         commandEncoder?: GPUCommandEncoder): void {
         const faces = [0, 3, 1, 4, 2, 5];
@@ -1012,13 +1042,17 @@ export class WebGPUTextureHelper {
     //                              Dispose
     //------------------------------------------------------------------------------
 
-    public releaseTexture(texture: InternalTexture): void {
-        const hardwareTexture = texture._hardwareTexture;
-        const irradianceTexture = texture._irradianceTexture;
-        const depthStencilTexture = texture._depthStencilTexture;
+    public releaseTexture(texture: InternalTexture | GPUTexture): void {
+        if (this._isInternalTexture(texture)) {
+            const hardwareTexture = texture._hardwareTexture;
+            const irradianceTexture = texture._irradianceTexture;
+            const depthStencilTexture = texture._depthStencilTexture;
 
-        // We can't destroy the objects just now because they could be used in the current frame - we delay the destroying after the end of the frame
-        this._deferredReleaseTextures.push([texture, hardwareTexture, irradianceTexture, depthStencilTexture]);
+            // We can't destroy the objects just now because they could be used in the current frame - we delay the destroying after the end of the frame
+            this._deferredReleaseTextures.push([texture, hardwareTexture, irradianceTexture, depthStencilTexture]);
+        } else {
+            this._deferredReleaseTextures.push([null, texture, null, null]);
+        }
     }
 
     public destroyDeferredTextures(): void {

+ 37 - 13
src/Engines/webgpuEngine.ts

@@ -262,7 +262,7 @@ export class WebGPUEngine extends Engine {
 
         options.deviceDescriptor = options.deviceDescriptor || { };
         options.swapChainFormat = options.swapChainFormat || WebGPUConstants.TextureFormat.BGRA8Unorm;
-        options.antialiasing = false; //options.antialiasing === undefined ? true : options.antialiasing;
+        options.antialiasing = options.antialiasing === undefined ? true : options.antialiasing;
         options.stencil = options.stencil ?? true;
         options.enableGPUDebugMarkers = options.enableGPUDebugMarkers ?? false;
 
@@ -451,7 +451,7 @@ export class WebGPUEngine extends Engine {
             instancedArrays: true,
             canUseTimestampForTimerQuery: false,
             blendMinMax: true,
-            maxMSAASamples: 8 // TODO WEBGPU what is the right value?
+            maxMSAASamples: 4 // TODO WEBGPU what is the right value?
         };
 
         this._caps.parallelShaderCompile = null as any;
@@ -512,7 +512,7 @@ export class WebGPUEngine extends Engine {
                 mipLevelCount: 1,
                 sampleCount: this._mainPassSampleCount,
                 dimension: WebGPUConstants.TextureDimension.E2d,
-                format: WebGPUConstants.TextureFormat.BGRA8Unorm,
+                format: this._options.swapChainFormat!,
                 usage: WebGPUConstants.TextureUsage.OutputAttachment,
             };
 
@@ -1116,6 +1116,10 @@ export class WebGPUEngine extends Engine {
         return Constants.TEXTUREFORMAT_RGBA;
     }
 
+    public updateTextureComparisonFunction(texture: InternalTexture, comparisonFunction: number): void {
+        texture._comparisonFunction = comparisonFunction;
+    }
+
     public createTexture(url: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<ISceneLike>, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
         buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
@@ -1869,7 +1873,7 @@ export class WebGPUEngine extends Engine {
             fullOptions.type = options.type === undefined ? Constants.TEXTURETYPE_UNSIGNED_INT : options.type;
             fullOptions.samplingMode = options.samplingMode === undefined ? Constants.TEXTURE_TRILINEAR_SAMPLINGMODE : options.samplingMode;
             fullOptions.format = options.format === undefined ? Constants.TEXTUREFORMAT_RGBA : options.format;
-            fullOptions.samples = options.samples ?? this._mainPassSampleCount;
+            fullOptions.samples = options.samples ?? 1;
         } else {
             fullOptions.generateMipMaps = <boolean>options;
             fullOptions.generateDepthBuffer = true;
@@ -1877,7 +1881,7 @@ export class WebGPUEngine extends Engine {
             fullOptions.type = Constants.TEXTURETYPE_UNSIGNED_INT;
             fullOptions.samplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE;
             fullOptions.format = Constants.TEXTUREFORMAT_RGBA;
-            fullOptions.samples = this._mainPassSampleCount;
+            fullOptions.samples = 1;
         }
 
         const texture = new InternalTexture(this, InternalTextureSource.RenderTarget);
@@ -1941,7 +1945,7 @@ export class WebGPUEngine extends Engine {
             type: Constants.TEXTURETYPE_UNSIGNED_INT,
             samplingMode: Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
             format: Constants.TEXTUREFORMAT_RGBA,
-            samples: this._mainPassSampleCount,
+            samples: 1,
             ...options
         };
         fullOptions.generateStencilBuffer = fullOptions.generateDepthBuffer && fullOptions.generateStencilBuffer;
@@ -2021,7 +2025,7 @@ export class WebGPUEngine extends Engine {
             bilinearFiltering: false,
             comparisonFunction: 0,
             generateStencil: false,
-            samples: this._mainPassSampleCount,
+            samples: 1,
             ...options
         };
 
@@ -2044,7 +2048,7 @@ export class WebGPUEngine extends Engine {
             bilinearFiltering: false,
             comparisonFunction: 0,
             generateStencil: false,
-            samples: this._mainPassSampleCount,
+            samples: 1,
             ...options
         };
 
@@ -2058,7 +2062,20 @@ export class WebGPUEngine extends Engine {
     }
 
     public updateRenderTargetTextureSampleCount(texture: Nullable<InternalTexture>, samples: number): number {
-        // TODO WEBGPU handle this
+        if (!texture || texture.samples === samples) {
+            return samples;
+        }
+
+        samples = Math.min(samples, this.getCaps().maxMSAASamples);
+
+        this._textureHelper.createMSAATexture(texture, samples);
+
+        if (texture._depthStencilTexture) {
+            this._textureHelper.createMSAATexture(texture._depthStencilTexture, samples);
+            texture._depthStencilTexture.samples = samples;
+        }
+
+        texture.samples = samples;
 
         return samples;
     }
@@ -2166,22 +2183,29 @@ export class WebGPUEngine extends Engine {
     private _startRenderTargetRenderPass(internalTexture: InternalTexture, clearColor: Nullable<IColor4Like>, clearDepth: boolean, clearStencil: boolean = false) {
         const gpuWrapper = internalTexture._hardwareTexture as WebGPUHardwareTexture;
         const gpuTexture = gpuWrapper.underlyingResource!;
+        const gpuMSAATexture = gpuWrapper.msaaTexture;
+
         const depthStencilTexture = internalTexture._depthStencilTexture;
-        const gpuDepthStencilTexture = depthStencilTexture?._hardwareTexture?.underlyingResource as Nullable<GPUTexture>;
+        const gpuDepthStencilWrapper = depthStencilTexture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;
+        const gpuDepthStencilTexture = gpuDepthStencilWrapper?.underlyingResource as Nullable<GPUTexture>;
+        const gpuDepthStencilMSAATexture = gpuDepthStencilWrapper?.msaaTexture;
 
         const colorTextureView = gpuTexture.createView(this._rttRenderPassWrapper.colorAttachmentViewDescriptor!);
+        const colorMSAATextureView = gpuMSAATexture?.createView(this._rttRenderPassWrapper.colorAttachmentViewDescriptor!);
         const depthTextureView = gpuDepthStencilTexture?.createView(this._rttRenderPassWrapper.depthAttachmentViewDescriptor!);
+        const depthMSAATextureView = gpuDepthStencilMSAATexture?.createView(this._rttRenderPassWrapper.depthAttachmentViewDescriptor!);
 
         this._debugPushGroup("render target pass", 1);
 
         this._rttRenderPassWrapper.renderPassDescriptor = {
             colorAttachments: [{
-                attachment: colorTextureView,
+                attachment: colorMSAATextureView ? colorMSAATextureView : colorTextureView,
+                resolveTarget: gpuMSAATexture ? colorTextureView : undefined,
                 loadValue: clearColor !== null ? clearColor : WebGPUConstants.LoadOp.Load,
-                storeOp: WebGPUConstants.StoreOp.Store
+                storeOp: gpuMSAATexture ? WebGPUConstants.StoreOp.Clear : WebGPUConstants.StoreOp.Store,
             }],
             depthStencilAttachment: depthStencilTexture && gpuDepthStencilTexture ? {
-                attachment: depthTextureView!,
+                attachment: depthMSAATextureView ? depthMSAATextureView : depthTextureView!,
                 depthLoadValue: clearDepth && depthStencilTexture._generateDepthBuffer ? this._clearDepthValue : WebGPUConstants.LoadOp.Load,
                 depthStoreOp: WebGPUConstants.StoreOp.Store,
                 stencilLoadValue: clearStencil && depthStencilTexture._generateStencilBuffer ? this._clearStencilValue : WebGPUConstants.LoadOp.Load,