فهرست منبع

Generate mipmaps with the right encoder

Popov72 4 سال پیش
والد
کامیت
1a0d683c49

+ 16 - 1
src/Engines/WebGPU/webgpuTextureHelper.ts

@@ -203,9 +203,24 @@ export class WebGPUTextureHelper {
     }
     }
 
 
     public generateCubeMipmaps(gpuTexture: GPUTexture, format: GPUTextureFormat, mipLevelCount: number, commandEncoder?: GPUCommandEncoder): void {
     public generateCubeMipmaps(gpuTexture: GPUTexture, format: GPUTextureFormat, mipLevelCount: number, commandEncoder?: GPUCommandEncoder): void {
+        const useOwnCommandEncoder = commandEncoder === undefined;
+
+        if (useOwnCommandEncoder) {
+            commandEncoder = this._device.createCommandEncoder({});
+        }
+
+        commandEncoder!.pushDebugGroup(`create cube mipmaps - ${mipLevelCount} levels`);
+
         for (let f = 0; f < 6; ++f) {
         for (let f = 0; f < 6; ++f) {
             this.generateMipmaps(gpuTexture, format, mipLevelCount, f, commandEncoder);
             this.generateMipmaps(gpuTexture, format, mipLevelCount, f, commandEncoder);
         }
         }
+
+        commandEncoder!.popDebugGroup();
+
+        if (useOwnCommandEncoder) {
+            this._device.defaultQueue.submit([commandEncoder!.finish()]);
+            commandEncoder = null as any;
+        }
     }
     }
 
 
     public generateMipmaps(gpuTexture: GPUTexture, format: GPUTextureFormat, mipLevelCount: number, faceIndex= 0, commandEncoder?: GPUCommandEncoder): void {
     public generateMipmaps(gpuTexture: GPUTexture, format: GPUTextureFormat, mipLevelCount: number, faceIndex= 0, commandEncoder?: GPUCommandEncoder): void {
@@ -217,7 +232,7 @@ export class WebGPUTextureHelper {
             commandEncoder = this._device.createCommandEncoder({});
             commandEncoder = this._device.createCommandEncoder({});
         }
         }
 
 
-        commandEncoder!.pushDebugGroup("create mipmaps");
+        commandEncoder!.pushDebugGroup(`create mipmaps for face #${faceIndex} - ${mipLevelCount} levels`);
 
 
         for (let i = 1; i < mipLevelCount; ++i) {
         for (let i = 1; i < mipLevelCount; ++i) {
             const passEncoder = commandEncoder!.beginRenderPass({
             const passEncoder = commandEncoder!.beginRenderPass({

+ 17 - 14
src/Engines/webgpuEngine.ts

@@ -1407,11 +1407,11 @@ export class WebGPUEngine extends Engine {
                         if (this._textureHelper.isImageBitmap(imageBitmap)) {
                         if (this._textureHelper.isImageBitmap(imageBitmap)) {
                             this._textureHelper.updateTexture(imageBitmap, gpuTextureWrapper.underlyingResource!, imageBitmap.width, imageBitmap.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
                             this._textureHelper.updateTexture(imageBitmap, gpuTextureWrapper.underlyingResource!, imageBitmap.width, imageBitmap.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
                             if (!noMipmap && !isCompressed) {
                             if (!noMipmap && !isCompressed) {
-                                this._generateMipmaps(texture);
+                                this._generateMipmaps(texture, this._uploadEncoder);
                             }
                             }
                         }
                         }
                     } else if (!noMipmap && !isCompressed) {
                     } else if (!noMipmap && !isCompressed) {
-                        this._generateMipmaps(texture);
+                        this._generateMipmaps(texture, this._uploadEncoder);
                     }
                     }
 
 
                     if (scene) {
                     if (scene) {
@@ -1454,7 +1454,7 @@ export class WebGPUEngine extends Engine {
                 this._textureHelper.updateCubeTextures(imageBitmaps, gpuTextureWrapper.underlyingResource!, width, height, gpuTextureWrapper.format, false, false, 0, 0, this._uploadEncoder);
                 this._textureHelper.updateCubeTextures(imageBitmaps, gpuTextureWrapper.underlyingResource!, width, height, gpuTextureWrapper.format, false, false, 0, 0, this._uploadEncoder);
 
 
                 if (!noMipmap) {
                 if (!noMipmap) {
-                    this._generateMipmaps(texture);
+                    this._generateMipmaps(texture, this._uploadEncoder);
                 }
                 }
 
 
                 texture.isReady = true;
                 texture.isReady = true;
@@ -1646,7 +1646,7 @@ export class WebGPUEngine extends Engine {
                 this._createGPUTextureForInternalTexture(texture);
                 this._createGPUTextureForInternalTexture(texture);
             }
             }
 
 
-            this._generateMipmaps(texture);
+            this._generateMipmaps(texture, texture.source === InternalTextureSource.RenderTarget ? this._renderTargetEncoder : undefined);
         }
         }
     }
     }
 
 
@@ -1914,13 +1914,15 @@ export class WebGPUEngine extends Engine {
         return gpuTextureWrapper;
         return gpuTextureWrapper;
     }
     }
 
 
-    private _generateMipmaps(texture: InternalTexture) {
+    private _generateMipmaps(texture: InternalTexture, commandEncoder?: GPUCommandEncoder) {
         const gpuTexture = texture._hardwareTexture?.underlyingResource;
         const gpuTexture = texture._hardwareTexture?.underlyingResource;
 
 
         if (!gpuTexture) {
         if (!gpuTexture) {
             return;
             return;
         }
         }
 
 
+        commandEncoder = commandEncoder ?? (this._currentRenderTarget && !this._currentRenderPass ? this._renderTargetEncoder : !this._currentRenderPass ? this._renderEncoder : this._uploadEncoder);
+
         const format = (texture._hardwareTexture as WebGPUHardwareTexture).format;
         const format = (texture._hardwareTexture as WebGPUHardwareTexture).format;
         const mipmapCount = WebGPUTextureHelper.computeNumMipmapLevels(texture.width, texture.height);
         const mipmapCount = WebGPUTextureHelper.computeNumMipmapLevels(texture.width, texture.height);
 
 
@@ -1931,9 +1933,9 @@ export class WebGPUEngine extends Engine {
         }
         }
 
 
         if (texture.isCube) {
         if (texture.isCube) {
-            this._textureHelper.generateCubeMipmaps(gpuTexture, format, mipmapCount, this._uploadEncoder);
+            this._textureHelper.generateCubeMipmaps(gpuTexture, format, mipmapCount, commandEncoder);
         } else {
         } else {
-            this._textureHelper.generateMipmaps(gpuTexture, format, mipmapCount, 0, this._uploadEncoder);
+            this._textureHelper.generateMipmaps(gpuTexture, format, mipmapCount, 0, commandEncoder);
         }
         }
     }
     }
 
 
@@ -1957,7 +1959,7 @@ export class WebGPUEngine extends Engine {
         createImageBitmap(canvas).then((bitmap) => {
         createImageBitmap(canvas).then((bitmap) => {
             this._textureHelper.updateTexture(bitmap, gpuTextureWrapper.underlyingResource!, width, height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, premulAlpha, 0, 0, this._uploadEncoder);
             this._textureHelper.updateTexture(bitmap, gpuTextureWrapper.underlyingResource!, width, height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, premulAlpha, 0, 0, this._uploadEncoder);
             if (texture.generateMipMaps) {
             if (texture.generateMipMaps) {
-                this._generateMipmaps(texture);
+                this._generateMipmaps(texture, this._uploadEncoder);
             }
             }
 
 
             texture.isReady = true;
             texture.isReady = true;
@@ -1994,7 +1996,7 @@ export class WebGPUEngine extends Engine {
         createImageBitmap(video).then((bitmap) => {
         createImageBitmap(video).then((bitmap) => {
             this._textureHelper.updateTexture(bitmap, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, !invertY, false, 0, 0, this._uploadEncoder);
             this._textureHelper.updateTexture(bitmap, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, !invertY, false, 0, 0, this._uploadEncoder);
             if (texture.generateMipMaps) {
             if (texture.generateMipMaps) {
-                this._generateMipmaps(texture);
+                this._generateMipmaps(texture, this._uploadEncoder);
             }
             }
 
 
             texture.isReady = true;
             texture.isReady = true;
@@ -2084,7 +2086,7 @@ export class WebGPUEngine extends Engine {
 
 
             this._textureHelper.updateTexture(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
             this._textureHelper.updateTexture(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
             if (texture.generateMipMaps) {
             if (texture.generateMipMaps) {
-                this._generateMipmaps(texture);
+                this._generateMipmaps(texture, this._uploadEncoder);
             }
             }
         }
         }
 
 
@@ -2110,7 +2112,7 @@ export class WebGPUEngine extends Engine {
 
 
         this._textureHelper.updateCubeTextures(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, gpuTextureWrapper.format, invertY, false, 0, 0, this._uploadEncoder);
         this._textureHelper.updateCubeTextures(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, gpuTextureWrapper.format, invertY, false, 0, 0, this._uploadEncoder);
         if (texture.generateMipMaps) {
         if (texture.generateMipMaps) {
-            this._generateMipmaps(texture);
+            this._generateMipmaps(texture, this._uploadEncoder);
         }
         }
 
 
         texture.isReady = true;
         texture.isReady = true;
@@ -2142,7 +2144,7 @@ export class WebGPUEngine extends Engine {
 
 
             this._textureHelper.updateTexture(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
             this._textureHelper.updateTexture(data, gpuTextureWrapper.underlyingResource!, texture.width, texture.height, texture.depth, gpuTextureWrapper.format, 0, 0, invertY, false, 0, 0, this._uploadEncoder);
             if (texture.generateMipMaps) {
             if (texture.generateMipMaps) {
-                this._generateMipmaps(texture);
+                this._generateMipmaps(texture, this._uploadEncoder);
             }
             }
         }
         }
 
 
@@ -2498,6 +2500,7 @@ export class WebGPUEngine extends Engine {
             }
             }
             this._debugPopGroup(1);
             this._debugPopGroup(1);
             this._resetCurrentViewport(1);
             this._resetCurrentViewport(1);
+            this._currentRenderPass = null;
         }
         }
     }
     }
 
 
@@ -2645,12 +2648,12 @@ export class WebGPUEngine extends Engine {
             this._endRenderTargetRenderPass();
             this._endRenderTargetRenderPass();
         }
         }
 
 
-        this._currentRenderTarget = null;
-
         if (texture.generateMipMaps && !disableGenerateMipMaps && !texture.isCube) {
         if (texture.generateMipMaps && !disableGenerateMipMaps && !texture.isCube) {
             this._generateMipmaps(texture);
             this._generateMipmaps(texture);
         }
         }
 
 
+        this._currentRenderTarget = null;
+
         this._currentRenderPass = this._mainRenderPass;
         this._currentRenderPass = this._mainRenderPass;
         this._setDepthTextureFormat(this._getMainDepthTextureFormat());
         this._setDepthTextureFormat(this._getMainDepthTextureFormat());
         this._setColorFormat(this._options.swapChainFormat!);
         this._setColorFormat(this._options.swapChainFormat!);

+ 5 - 5
src/Materials/Textures/Procedurals/proceduralTexture.ts

@@ -593,11 +593,6 @@ export class ProceduralTexture extends Texture {
 
 
                 // Draw order
                 // Draw order
                 engine.drawElementsType(Material.TriangleFillMode, 0, 6);
                 engine.drawElementsType(Material.TriangleFillMode, 0, 6);
-
-                // Mipmaps
-                if (face === 5) {
-                    engine.generateMipMapsForCubemap(this._texture);
-                }
             }
             }
         } else {
         } else {
             engine.bindFramebuffer(this._texture, 0, undefined, undefined, true);
             engine.bindFramebuffer(this._texture, 0, undefined, undefined, true);
@@ -617,6 +612,11 @@ export class ProceduralTexture extends Texture {
         // Unbind
         // Unbind
         engine.unBindFramebuffer(this._texture, this.isCube);
         engine.unBindFramebuffer(this._texture, this.isCube);
 
 
+        // Mipmaps
+        if (this.isCube) {
+            engine.generateMipMapsForCubemap(this._texture);
+        }
+
         engine._debugPopGroup(1);
         engine._debugPopGroup(1);
 
 
         if (this.onGenerated) {
         if (this.onGenerated) {

+ 2 - 1
src/Materials/Textures/renderTargetTexture.ts

@@ -937,11 +937,12 @@ export class RenderTargetTexture extends Texture {
         }
         }
 
 
         // Unbind
         // Unbind
+        this.unbindFrameBuffer(engine, faceIndex);
+
         if (this.isCube && faceIndex === 5) {
         if (this.isCube && faceIndex === 5) {
             engine.generateMipMapsForCubemap(this._texture);
             engine.generateMipMapsForCubemap(this._texture);
         }
         }
 
 
-        this.unbindFrameBuffer(engine, faceIndex);
         engine._debugPopGroup(1);
         engine._debugPopGroup(1);
     }
     }