فهرست منبع

Fix render pipeline cache

Popov72 4 سال پیش
والد
کامیت
8af7b53378
3فایلهای تغییر یافته به همراه140 افزوده شده و 550 حذف شده
  1. 84 52
      src/Engines/WebGPU/webgpuCacheRenderPipeline.ts
  2. 7 0
      src/Engines/WebGPU/webgpuCacheSampler.ts
  3. 49 498
      src/Engines/webgpuEngineCache.ts

+ 84 - 52
src/Engines/WebGPU/webgpuCacheRenderPipeline.ts

@@ -14,14 +14,15 @@ enum StatePosition {
     DepthBias = 2,
     DepthBias = 2,
     DepthBiasClamp = 3,
     DepthBiasClamp = 3,
     DepthBiasSlopeScale = 4,
     DepthBiasSlopeScale = 4,
-    MRTAttachments = 5,
-    ColorStates = 6,
-    DepthStencilState = 7,
-    StencilReadMask = 8,
-    StencilWriteMask = 9,
-    VertexState = 10,
-
-    NumStates = 11
+    MRTAttachments1 = 5,
+    MRTAttachments2 = 6,
+    ColorStates = 7,
+    DepthStencilState = 8,
+    StencilReadMask = 9,
+    StencilWriteMask = 10,
+    VertexState = 11,
+
+    NumStates = 12
 }
 }
 
 
 const textureFormatToIndex: { [name: string]: number } = {
 const textureFormatToIndex: { [name: string]: number } = {
@@ -122,6 +123,8 @@ export class WebGPUCacheRenderPipeline {
     public static NumCacheMiss = 0;
     public static NumCacheMiss = 0;
     public static NumPipelineCreationLastFrame = 0;
     public static NumPipelineCreationLastFrame = 0;
 
 
+    public disabled: boolean;
+
     private static _Cache: { [hash: string]: GPURenderPipeline } = {};
     private static _Cache: { [hash: string]: GPURenderPipeline } = {};
     private static _NumPipelineCreationCurrentFrame = 0;
     private static _NumPipelineCreationCurrentFrame = 0;
 
 
@@ -130,6 +133,7 @@ export class WebGPUCacheRenderPipeline {
     private _isDirty: boolean;
     private _isDirty: boolean;
     private _currentRenderPipeline: GPURenderPipeline;
     private _currentRenderPipeline: GPURenderPipeline;
     private _emptyVertexBuffer: VertexBuffer;
     private _emptyVertexBuffer: VertexBuffer;
+    //private _numFrames: number;
 
 
     private _shaderId: number;
     private _shaderId: number;
     private _alphaToCoverageEnabled: boolean;
     private _alphaToCoverageEnabled: boolean;
@@ -143,7 +147,8 @@ export class WebGPUCacheRenderPipeline {
     private _depthBiasSlopeScale: number;
     private _depthBiasSlopeScale: number;
     private _colorFormat: number;
     private _colorFormat: number;
     private _webgpuColorFormat: GPUTextureFormat;
     private _webgpuColorFormat: GPUTextureFormat;
-    private _mrtAttachments: number;
+    private _mrtAttachments1: number;
+    private _mrtAttachments2: number;
     private _mrtFormats: GPUTextureFormat[];
     private _mrtFormats: GPUTextureFormat[];
     private _alphaBlendEnabled: boolean;
     private _alphaBlendEnabled: boolean;
     private _alphaBlendFuncParams: Array<Nullable<number>>;
     private _alphaBlendFuncParams: Array<Nullable<number>>;
@@ -173,28 +178,41 @@ export class WebGPUCacheRenderPipeline {
         this._states.length = StatePosition.NumStates;
         this._states.length = StatePosition.NumStates;
         this._emptyVertexBuffer = emptyVertexBuffer;
         this._emptyVertexBuffer = emptyVertexBuffer;
         this._mrtFormats = [];
         this._mrtFormats = [];
+        this.disabled = false;
+        //this._numFrames = 0;
         this.reset();
         this.reset();
     }
     }
 
 
     public reset(): void {
     public reset(): void {
         this._isDirty = true;
         this._isDirty = true;
         this.setAlphaToCoverage(false);
         this.setAlphaToCoverage(false);
-        this.resetDepthCullingState(); //
+        this.resetDepthCullingState();
         this.setClampDepth(false);
         this.setClampDepth(false);
         this.setDepthBias(0);
         this.setDepthBias(0);
         this.setDepthBiasClamp(0);
         this.setDepthBiasClamp(0);
-        this.setColorFormat(WebGPUConstants.TextureFormat.BGRA8Unorm); //
-        this.setMRTAttachments([], []); //
-        this.setAlphaBlendEnabled(false); //
-        this.setAlphaBlendFactors([null, null, null, null], [null, null]); //
-        this.setWriteMask(0xF); //
-        this.setDepthStencilFormat(WebGPUConstants.TextureFormat.Depth24PlusStencil8); //
-        this.setStencilEnabled(false); //
-        this.resetStencilState(); //
-        this.setBuffers(null, null); //
+        this.setColorFormat(WebGPUConstants.TextureFormat.BGRA8Unorm);
+        this.setMRTAttachments([], []);
+        this.setAlphaBlendEnabled(false);
+        this.setAlphaBlendFactors([null, null, null, null], [null, null]);
+        this.setWriteMask(0xF);
+        this.setDepthStencilFormat(WebGPUConstants.TextureFormat.Depth24PlusStencil8);
+        this.setStencilEnabled(false);
+        this.resetStencilState();
+        this.setBuffers(null, null);
     }
     }
 
 
     public getRenderPipeline(fillMode: number, effect: Effect, sampleCount: number): GPURenderPipeline {
     public getRenderPipeline(fillMode: number, effect: Effect, sampleCount: number): GPURenderPipeline {
+        if (this.disabled) {
+            const topology = WebGPUCacheRenderPipeline._GetTopology(fillMode);
+
+            this._currentRenderPipeline = this._createRenderPipeline(effect, topology, sampleCount);
+
+            WebGPUCacheRenderPipeline.NumCacheMiss++;
+            WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame++;
+
+            return this._currentRenderPipeline;
+        }
+
         this._setShaderStage(effect.uniqueId);
         this._setShaderStage(effect.uniqueId);
         this._setRasterizationState(fillMode, sampleCount);
         this._setRasterizationState(fillMode, sampleCount);
         this._setColorStates();
         this._setColorStates();
@@ -227,6 +245,7 @@ export class WebGPUCacheRenderPipeline {
     }
     }
 
 
     public endFrame(): void {
     public endFrame(): void {
+        //this._numFrames++;
         WebGPUCacheRenderPipeline.NumPipelineCreationLastFrame = WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame;
         WebGPUCacheRenderPipeline.NumPipelineCreationLastFrame = WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame;
         WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame = 0;
         WebGPUCacheRenderPipeline._NumPipelineCreationCurrentFrame = 0;
     }
     }
@@ -235,12 +254,6 @@ export class WebGPUCacheRenderPipeline {
         this._alphaToCoverageEnabled = enabled;
         this._alphaToCoverageEnabled = enabled;
     }
     }
 
 
-    public setState(cullEnabled: boolean, frontFace: number, cullFace: number): void {
-        this._cullEnabled = cullEnabled;
-        this._frontFace = frontFace;
-        this._cullFace = cullFace;
-    }
-
     public setFrontFace(frontFace: number): void {
     public setFrontFace(frontFace: number): void {
         this._frontFace = frontFace;
         this._frontFace = frontFace;
     }
     }
@@ -258,13 +271,17 @@ export class WebGPUCacheRenderPipeline {
     }
     }
 
 
     public resetDepthCullingState(): void {
     public resetDepthCullingState(): void {
-        this._depthWriteEnabled = true;
-        this._depthTestEnabled = true;
-        this._depthCompare = Constants.LEQUAL - 0x0200;
-        this._cullFace = 1;
-        this._cullEnabled = false;
-        this._frontFace = 2;
-        this.setDepthBiasSlopeScale(0);
+        this.setDepthCullingState(false, 2, 1, 0, true, true, Constants.ALWAYS);
+    }
+
+    public setDepthCullingState(cullEnabled: boolean, frontFace: number, cullFace: number, zOffset: number, depthTestEnabled: boolean, depthWriteEnabled: boolean, depthCompare: Nullable<number>): void {
+        this._depthWriteEnabled = depthWriteEnabled;
+        this._depthTestEnabled = depthTestEnabled;
+        this._depthCompare = (depthCompare ?? Constants.ALWAYS) - 0x0200;
+        this._cullFace = cullFace;
+        this._cullEnabled = cullEnabled;
+        this._frontFace = frontFace;
+        this.setDepthBiasSlopeScale(zOffset);
     }
     }
 
 
     public setDepthBias(depthBias: number): void {
     public setDepthBias(depthBias: number): void {
@@ -298,28 +315,34 @@ export class WebGPUCacheRenderPipeline {
 
 
     public setMRTAttachments(attachments: number[], textureArray: InternalTexture[]): void {
     public setMRTAttachments(attachments: number[], textureArray: InternalTexture[]): void {
         if (attachments.length > 10) {
         if (attachments.length > 10) {
-            // If we want more than 10 attachments we need to change this method but 10 seems plenty and it allows to use some bit shifting for faster operations
+            // If we want more than 10 attachments we need to change this method but 10 seems plenty
             // Note we can do better without changing this method if only dealing with texture formats that can be used as output attachments
             // Note we can do better without changing this method if only dealing with texture formats that can be used as output attachments
             // It could allow to use 5 bits (or even less) to code a texture format. For the time being, we use 6 bits as we need 58 different values (2^6=64)
             // It could allow to use 5 bits (or even less) to code a texture format. For the time being, we use 6 bits as we need 58 different values (2^6=64)
-            // so we can encode 10 texture formats in 64 bits
+            // so we can encode 5 texture formats in 32 bits
             throw "Can't handle more than 10 attachments for a MRT in cache render pipeline!";
             throw "Can't handle more than 10 attachments for a MRT in cache render pipeline!";
         }
         }
-        let bits = 0, mask = 0;
+        let bits: number[] = [0, 0], indexBits = 0, mask = 0;
         this._mrtFormats.length = attachments.length;
         this._mrtFormats.length = attachments.length;
         for (let i = 0; i < attachments.length; ++i) {
         for (let i = 0; i < attachments.length; ++i) {
             const index = attachments[i];
             const index = attachments[i];
             const texture = textureArray[index - 1];
             const texture = textureArray[index - 1];
             const gpuWrapper = texture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;
             const gpuWrapper = texture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;
-            const gpuTexture = gpuWrapper?.underlyingResource as Nullable<WebGPUHardwareTexture>;
 
 
-            this._mrtFormats[i] = gpuTexture?.format ?? WebGPUConstants.TextureFormat.BGRA8Unorm;
+            this._mrtFormats[i] = gpuWrapper?.format ?? this._webgpuColorFormat;
 
 
-            bits += textureFormatToIndex[this._mrtFormats[i]] << mask;
+            bits[indexBits] += textureFormatToIndex[this._mrtFormats[i]] << mask;
             mask += 6;
             mask += 6;
+
+            if (mask >= 32) {
+                mask = 0;
+                indexBits++;
+            }
         }
         }
-        if (this._mrtAttachments !== bits) {
-            this._mrtAttachments = bits;
-            this._states[StatePosition.MRTAttachments] = bits.toString();
+        if (this._mrtAttachments1 !== bits[0] || this._mrtAttachments2 !== bits[1]) {
+            this._mrtAttachments1 = bits[0];
+            this._mrtAttachments2 = bits[1];
+            this._states[StatePosition.MRTAttachments1] = bits[0].toString();
+            this._states[StatePosition.MRTAttachments2] = bits[1].toString();
             this._isDirty = true;
             this._isDirty = true;
         }
         }
     }
     }
@@ -351,7 +374,7 @@ export class WebGPUCacheRenderPipeline {
     }
     }
 
 
     public setDepthCompare(func: Nullable<number>): void {
     public setDepthCompare(func: Nullable<number>): void {
-        this._depthCompare = (func ?? Constants.LEQUAL) - 0x0200;
+        this._depthCompare = (func ?? Constants.ALWAYS) - 0x0200;
     }
     }
 
 
     public setStencilEnabled(enabled: boolean): void {
     public setStencilEnabled(enabled: boolean): void {
@@ -359,7 +382,7 @@ export class WebGPUCacheRenderPipeline {
     }
     }
 
 
     public setStencilCompare(func: Nullable<number>): void {
     public setStencilCompare(func: Nullable<number>): void {
-        this._stencilFrontCompare = (func ?? Constants.LEQUAL) - 0x0200;
+        this._stencilFrontCompare = (func ?? Constants.ALWAYS) - 0x0200;
     }
     }
 
 
     public setStencilDepthFailOp(op: Nullable<number>): void {
     public setStencilDepthFailOp(op: Nullable<number>): void {
@@ -391,12 +414,17 @@ export class WebGPUCacheRenderPipeline {
     }
     }
 
 
     public resetStencilState(): void {
     public resetStencilState(): void {
-        this._stencilFrontCompare = Constants.ALWAYS - 0x0200;
-        this._stencilFrontDepthFailOp = stencilOpToIndex[Constants.KEEP];
-        this._stencilFrontPassOp = stencilOpToIndex[Constants.REPLACE];
-        this._stencilFrontFailOp = stencilOpToIndex[Constants.KEEP];
-        this.setStencilReadMask(0xFF);
-        this.setStencilWriteMask(0xFF);
+        this.setStencilState(false, Constants.ALWAYS, Constants.KEEP, Constants.REPLACE, Constants.KEEP, 0xFF, 0xFF);
+    }
+
+    public setStencilState(stencilEnabled: boolean, compare: Nullable<number>, depthFailOp: Nullable<number>, passOp: Nullable<number>, failOp: Nullable<number>, readMask: number, writeMask: number): void {
+        this._stencilEnabled = stencilEnabled;
+        this._stencilFrontCompare = (compare ?? Constants.ALWAYS) - 0x0200;
+        this._stencilFrontDepthFailOp = depthFailOp === null ? 1 /* KEEP */ : stencilOpToIndex[depthFailOp];
+        this._stencilFrontPassOp = passOp === null ? 2 /* REPLACE */ : stencilOpToIndex[passOp];
+        this._stencilFrontFailOp = failOp === null ? 1 /* KEEP */ : stencilOpToIndex[failOp];
+        this.setStencilReadMask(readMask);
+        this.setStencilWriteMask(writeMask);
     }
     }
 
 
     public setBuffers(vertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>, indexBuffer: Nullable<DataBuffer>): void {
     public setBuffers(vertexBuffers: Nullable<{ [key: string]: Nullable<VertexBuffer> }>, indexBuffer: Nullable<DataBuffer>): void {
@@ -694,7 +722,7 @@ export class WebGPUCacheRenderPipeline {
 
 
     private _setDepthStencilState(): void {
     private _setDepthStencilState(): void {
         let stencilState = !this._stencilEnabled ?
         let stencilState = !this._stencilEnabled ?
-            0 /* NEVER */ + (1 /* KEEP */ << 3) + (1 /* KEEP */ << 6) + (1 /* KEEP */ << 9) :
+            7 /* ALWAYS */ + (1 /* KEEP */ << 3) + (1 /* KEEP */ << 6) + (1 /* KEEP */ << 9) :
             this._stencilFrontCompare + (this._stencilFrontDepthFailOp << 3) + (this._stencilFrontPassOp << 6) + (this._stencilFrontFailOp << 9);
             this._stencilFrontCompare + (this._stencilFrontDepthFailOp << 3) + (this._stencilFrontPassOp << 6) + (this._stencilFrontFailOp << 9);
 
 
         const depthStencilState =
         const depthStencilState =
@@ -870,7 +898,7 @@ export class WebGPUCacheRenderPipeline {
         const alphaBlend = this._getAphaBlendState();
         const alphaBlend = this._getAphaBlendState();
         const colorBlend = this._getColorBlendState();
         const colorBlend = this._getColorBlendState();
 
 
-        if (this._mrtAttachments > 0) {
+        if (this._mrtAttachments1 > 0) {
             for (let i = 0; i < this._mrtFormats.length; ++i) {
             for (let i = 0; i < this._mrtFormats.length; ++i) {
                 colorStates.push({
                 colorStates.push({
                     format: this._mrtFormats[i],
                     format: this._mrtFormats[i],
@@ -895,6 +923,10 @@ export class WebGPUCacheRenderPipeline {
             passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilFrontPassOp)
             passOp: WebGPUCacheRenderPipeline._GetStencilOpFunction(this._stencilFrontPassOp)
         };
         };
 
 
+        /*if (this._numFrames < 10) {
+            console.log(colorStates);
+        }*/
+
         return this._device.createRenderPipeline({
         return this._device.createRenderPipeline({
             layout: pipelineLayout,
             layout: pipelineLayout,
             ...webgpuPipelineContext.stages!,
             ...webgpuPipelineContext.stages!,
@@ -911,7 +943,7 @@ export class WebGPUCacheRenderPipeline {
             sampleCount,
             sampleCount,
             depthStencilState: this._webgpuDepthStencilFormat === undefined ? undefined : {
             depthStencilState: this._webgpuDepthStencilFormat === undefined ? undefined : {
                 depthWriteEnabled: this._depthWriteEnabled,
                 depthWriteEnabled: this._depthWriteEnabled,
-                depthCompare: WebGPUCacheRenderPipeline._GetCompareFunction(this._depthCompare),
+                depthCompare: this._depthTestEnabled ? WebGPUCacheRenderPipeline._GetCompareFunction(this._depthCompare) : WebGPUConstants.CompareFunction.Always,
                 format: this._webgpuDepthStencilFormat,
                 format: this._webgpuDepthStencilFormat,
                 stencilFront: stencilFrontBack,
                 stencilFront: stencilFrontBack,
                 stencilBack: stencilFrontBack,
                 stencilBack: stencilFrontBack,

+ 7 - 0
src/Engines/WebGPU/webgpuCacheSampler.ts

@@ -54,8 +54,11 @@ export class WebGPUCacheSampler {
     private _samplers: { [hash: number]: GPUSampler } = {};
     private _samplers: { [hash: number]: GPUSampler } = {};
     private _device: GPUDevice;
     private _device: GPUDevice;
 
 
+    public disabled: boolean;
+
     constructor(device: GPUDevice) {
     constructor(device: GPUDevice) {
         this._device = device;
         this._device = device;
+        this.disabled = false;
     }
     }
 
 
     private static _GetSamplerHashCode(texture: InternalTexture): number {
     private static _GetSamplerHashCode(texture: InternalTexture): number {
@@ -232,6 +235,10 @@ export class WebGPUCacheSampler {
     }
     }
 
 
     public getSampler(internalTexture: InternalTexture, bypassCache = false): GPUSampler {
     public getSampler(internalTexture: InternalTexture, bypassCache = false): GPUSampler {
+        if (this.disabled) {
+            return this._device.createSampler(WebGPUCacheSampler._GetSamplerDescriptor(internalTexture));
+        }
+
         const hash = bypassCache ? 0 : WebGPUCacheSampler._GetSamplerHashCode(internalTexture);
         const hash = bypassCache ? 0 : WebGPUCacheSampler._GetSamplerHashCode(internalTexture);
 
 
         let sampler = bypassCache ? undefined : this._samplers[hash];
         let sampler = bypassCache ? undefined : this._samplers[hash];

+ 49 - 498
src/Engines/webgpuEngineCache.ts

@@ -84,7 +84,6 @@ export class WebGPUEngineCache extends Engine {
     private _shaderManager: WebGPUShaderManager;
     private _shaderManager: WebGPUShaderManager;
     private _cacheSampler: WebGPUCacheSampler;
     private _cacheSampler: WebGPUCacheSampler;
     private _cacheRenderPipeline: WebGPUCacheRenderPipeline;
     private _cacheRenderPipeline: WebGPUCacheRenderPipeline;
-    private _cacheRenderPipelineClear: WebGPUCacheRenderPipeline;
     private _emptyVertexBuffer: VertexBuffer;
     private _emptyVertexBuffer: VertexBuffer;
     private _lastCachedWrapU: number;
     private _lastCachedWrapU: number;
     private _lastCachedWrapV: number;
     private _lastCachedWrapV: number;
@@ -146,6 +145,32 @@ export class WebGPUEngineCache extends Engine {
     public dbgShowWarningsNotImplemented = false;
     public dbgShowWarningsNotImplemented = false;
 
 
     /**
     /**
+     * Sets this to true to disable the cache for the samplers. You should do it only for testing purpose!
+     */
+    public get disableCacheSamplers(): boolean {
+        return this._cacheSampler ? this._cacheSampler.disabled : false;
+    }
+
+    public set disableCacheSamplers(disable: boolean) {
+        if (this._cacheSampler) {
+            this._cacheSampler.disabled = disable;
+        }
+    }
+
+    /**
+     * Sets this to true to disable the cache for the render pipelines. You should do it only for testing purpose!
+     */
+    public get disableCacheRenderPipelines(): boolean {
+        return this._cacheRenderPipeline ? this._cacheRenderPipeline.disabled : false;
+    }
+
+    public set disableCacheRenderPipelines(disable: boolean) {
+        if (this._cacheRenderPipeline) {
+            this._cacheRenderPipeline.disabled = disable;
+        }
+    }
+
+    /**
      * Gets a boolean indicating if the engine can be instanciated (ie. if a WebGPU context can be found)
      * Gets a boolean indicating if the engine can be instanciated (ie. if a WebGPU context can be found)
      * @returns true if the engine can be created
      * @returns true if the engine can be created
      */
      */
@@ -331,7 +356,9 @@ export class WebGPUEngineCache extends Engine {
                 this._emptyVertexBuffer = new VertexBuffer(this, [0], "", false, false, 1, false, 0, 1);
                 this._emptyVertexBuffer = new VertexBuffer(this, [0], "", false, false, 1, false, 0, 1);
 
 
                 this._cacheRenderPipeline = new WebGPUCacheRenderPipeline(this._device, this._emptyVertexBuffer);
                 this._cacheRenderPipeline = new WebGPUCacheRenderPipeline(this._device, this._emptyVertexBuffer);
-                this._cacheRenderPipelineClear = new WebGPUCacheRenderPipeline(this._device, this._emptyVertexBuffer);
+
+                this._cacheRenderPipeline.setDepthCompare(this._depthCullingState.depthFunc);
+                //this._cacheRenderPipeline.disabled = true;
 
 
                 this._textureHelper.setCommandEncoder(this._uploadEncoder);
                 this._textureHelper.setCommandEncoder(this._uploadEncoder);
 
 
@@ -598,6 +625,7 @@ export class WebGPUEngineCache extends Engine {
             this._depthCullingState.reset();
             this._depthCullingState.reset();
             this._depthCullingState.depthFunc = Constants.LEQUAL;
             this._depthCullingState.depthFunc = Constants.LEQUAL;
             this._cacheRenderPipeline.resetDepthCullingState();
             this._cacheRenderPipeline.resetDepthCullingState();
+            this._cacheRenderPipeline.setDepthCompare(Constants.LEQUAL);
 
 
             this._alphaState.reset();
             this._alphaState.reset();
             this._alphaMode = Constants.ALPHA_ADD;
             this._alphaMode = Constants.ALPHA_ADD;
@@ -2760,10 +2788,6 @@ export class WebGPUEngineCache extends Engine {
         return this._currentRenderPass!;
         return this._currentRenderPass!;
     }
     }
 
 
-    private _currentRenderPassIsMRT(): boolean {
-        return !!this._currentRenderTarget?._attachments ?? false;
-    }
-
     private _startMainRenderPass(setClearStates: boolean, clearColor?: Nullable<IColor4Like>, clearDepth?: boolean, clearStencil?: boolean): void {
     private _startMainRenderPass(setClearStates: boolean, clearColor?: Nullable<IColor4Like>, clearDepth?: boolean, clearStencil?: boolean): void {
         if (this._mainRenderPassWrapper.renderPass) {
         if (this._mainRenderPassWrapper.renderPass) {
             this._endMainRenderPass();
             this._endMainRenderPass();
@@ -3102,7 +3126,6 @@ export class WebGPUEngineCache extends Engine {
     //------------------------------------------------------------------------------
     //------------------------------------------------------------------------------
 
 
     public setZOffset(value: number): void {
     public setZOffset(value: number): void {
-        this._cacheRenderPipeline.setDepthBiasSlopeScale(value);
         if (value !== this._depthCullingState.zOffset) {
         if (value !== this._depthCullingState.zOffset) {
             this._depthCullingState.zOffset = value;
             this._depthCullingState.zOffset = value;
         }
         }
@@ -3126,35 +3149,30 @@ export class WebGPUEngineCache extends Engine {
     }
     }
 
 
     public setDepthBuffer(enable: boolean): void {
     public setDepthBuffer(enable: boolean): void {
-        this._cacheRenderPipeline.setDepthTestEnabled(enable);
         if (this._depthCullingState.depthTest !== enable) {
         if (this._depthCullingState.depthTest !== enable) {
             this._depthCullingState.depthTest = enable;
             this._depthCullingState.depthTest = enable;
         }
         }
     }
     }
 
 
     public setDepthWrite(enable: boolean): void {
     public setDepthWrite(enable: boolean): void {
-        this._cacheRenderPipeline.setDepthWriteEnabled(enable);
         if (this._depthCullingState.depthMask !== enable) {
         if (this._depthCullingState.depthMask !== enable) {
             this._depthCullingState.depthMask = enable;
             this._depthCullingState.depthMask = enable;
         }
         }
     }
     }
 
 
     public setStencilBuffer(enable: boolean): void {
     public setStencilBuffer(enable: boolean): void {
-        this._cacheRenderPipeline.setStencilEnabled(enable);
         if (this._stencilState.stencilTest !== enable) {
         if (this._stencilState.stencilTest !== enable) {
             this._stencilState.stencilTest = enable;
             this._stencilState.stencilTest = enable;
         }
         }
     }
     }
 
 
     public setStencilMask(mask: number): void {
     public setStencilMask(mask: number): void {
-        this._cacheRenderPipeline.setStencilWriteMask(mask);
         if (this._stencilState.stencilMask !== mask) {
         if (this._stencilState.stencilMask !== mask) {
             this._stencilState.stencilMask = mask;
             this._stencilState.stencilMask = mask;
         }
         }
     }
     }
 
 
     public setStencilFunction(stencilFunc: number) {
     public setStencilFunction(stencilFunc: number) {
-        this._cacheRenderPipeline.setStencilCompare(stencilFunc);
         if (this._stencilState.stencilFunc !== stencilFunc) {
         if (this._stencilState.stencilFunc !== stencilFunc) {
             this._stencilState.stencilFunc = stencilFunc;
             this._stencilState.stencilFunc = stencilFunc;
         }
         }
@@ -3167,28 +3185,24 @@ export class WebGPUEngineCache extends Engine {
     }
     }
 
 
     public setStencilFunctionMask(mask: number) {
     public setStencilFunctionMask(mask: number) {
-        this._cacheRenderPipeline.setStencilReadMask(mask);
         if (this._stencilState.stencilFuncMask !== mask) {
         if (this._stencilState.stencilFuncMask !== mask) {
             this._stencilState.stencilFuncMask = mask;
             this._stencilState.stencilFuncMask = mask;
         }
         }
     }
     }
 
 
     public setStencilOperationFail(operation: number): void {
     public setStencilOperationFail(operation: number): void {
-        this._cacheRenderPipeline.setStencilFailOp(operation);
         if (this._stencilState.stencilOpStencilFail !== operation) {
         if (this._stencilState.stencilOpStencilFail !== operation) {
             this._stencilState.stencilOpStencilFail = operation;
             this._stencilState.stencilOpStencilFail = operation;
         }
         }
     }
     }
 
 
     public setStencilOperationDepthFail(operation: number): void {
     public setStencilOperationDepthFail(operation: number): void {
-        this._cacheRenderPipeline.setStencilDepthFailOp(operation);
         if (this._stencilState.stencilOpDepthFail !== operation) {
         if (this._stencilState.stencilOpDepthFail !== operation) {
             this._stencilState.stencilOpDepthFail = operation;
             this._stencilState.stencilOpDepthFail = operation;
         }
         }
     }
     }
 
 
     public setStencilOperationPass(operation: number): void {
     public setStencilOperationPass(operation: number): void {
-        this._cacheRenderPipeline.setStencilPassOp(operation);
         if (this._stencilState.stencilOpStencilDepthPass !== operation) {
         if (this._stencilState.stencilOpStencilDepthPass !== operation) {
             this._stencilState.stencilOpStencilDepthPass = operation;
             this._stencilState.stencilOpStencilDepthPass = operation;
         }
         }
@@ -3203,123 +3217,35 @@ export class WebGPUEngineCache extends Engine {
     }
     }
 
 
     public setDepthFunction(depthFunc: number) {
     public setDepthFunction(depthFunc: number) {
-        this._cacheRenderPipeline.setDepthCompare(depthFunc);
         if (this._depthCullingState.depthFunc !== depthFunc) {
         if (this._depthCullingState.depthFunc !== depthFunc) {
             this._depthCullingState.depthFunc = depthFunc;
             this._depthCullingState.depthFunc = depthFunc;
         }
         }
     }
     }
 
 
     public setDepthFunctionToGreater(): void {
     public setDepthFunctionToGreater(): void {
-        this._cacheRenderPipeline.setDepthCompare(Constants.GREATER);
         if (this._depthCullingState.depthFunc !== Constants.GREATER) {
         if (this._depthCullingState.depthFunc !== Constants.GREATER) {
             this._depthCullingState.depthFunc = Constants.GREATER;
             this._depthCullingState.depthFunc = Constants.GREATER;
         }
         }
     }
     }
 
 
     public setDepthFunctionToGreaterOrEqual(): void {
     public setDepthFunctionToGreaterOrEqual(): void {
-        this._cacheRenderPipeline.setDepthCompare(Constants.GEQUAL);
         if (this._depthCullingState.depthFunc !== Constants.GEQUAL) {
         if (this._depthCullingState.depthFunc !== Constants.GEQUAL) {
             this._depthCullingState.depthFunc = Constants.GEQUAL;
             this._depthCullingState.depthFunc = Constants.GEQUAL;
         }
         }
     }
     }
 
 
     public setDepthFunctionToLess(): void {
     public setDepthFunctionToLess(): void {
-        this._cacheRenderPipeline.setDepthCompare(Constants.LESS);
         if (this._depthCullingState.depthFunc !== Constants.LESS) {
         if (this._depthCullingState.depthFunc !== Constants.LESS) {
             this._depthCullingState.depthFunc = Constants.LESS;
             this._depthCullingState.depthFunc = Constants.LESS;
         }
         }
     }
     }
 
 
     public setDepthFunctionToLessOrEqual(): void {
     public setDepthFunctionToLessOrEqual(): void {
-        this._cacheRenderPipeline.setDepthCompare(Constants.LEQUAL);
         if (this._depthCullingState.depthFunc !== Constants.LEQUAL) {
         if (this._depthCullingState.depthFunc !== Constants.LEQUAL) {
             this._depthCullingState.depthFunc = Constants.LEQUAL;
             this._depthCullingState.depthFunc = Constants.LEQUAL;
         }
         }
     }
     }
 
 
-    private _indexFormatInRenderPass(topology: GPUPrimitiveTopology): boolean {
-        return  topology === WebGPUConstants.PrimitiveTopology.PointList ||
-                topology === WebGPUConstants.PrimitiveTopology.LineList ||
-                topology === WebGPUConstants.PrimitiveTopology.TriangleList;
-    }
-
-    private _getTopology(fillMode: number): GPUPrimitiveTopology {
-        switch (fillMode) {
-            // Triangle views
-            case Constants.MATERIAL_TriangleFillMode:
-                return WebGPUConstants.PrimitiveTopology.TriangleList;
-            case Constants.MATERIAL_PointFillMode:
-                return WebGPUConstants.PrimitiveTopology.PointList;
-            case Constants.MATERIAL_WireFrameFillMode:
-                return WebGPUConstants.PrimitiveTopology.LineList;
-            // Draw modes
-            case Constants.MATERIAL_PointListDrawMode:
-                return WebGPUConstants.PrimitiveTopology.PointList;
-            case Constants.MATERIAL_LineListDrawMode:
-                return WebGPUConstants.PrimitiveTopology.LineList;
-            case Constants.MATERIAL_LineLoopDrawMode:
-                // return this._gl.LINE_LOOP;
-                // TODO WEBGPU. Line Loop Mode Fallback at buffer load time.
-                throw "LineLoop is an unsupported fillmode in WebGPU";
-            case Constants.MATERIAL_LineStripDrawMode:
-                return WebGPUConstants.PrimitiveTopology.LineStrip;
-            case Constants.MATERIAL_TriangleStripDrawMode:
-                return WebGPUConstants.PrimitiveTopology.TriangleStrip;
-            case Constants.MATERIAL_TriangleFanDrawMode:
-                // return this._gl.TRIANGLE_FAN;
-                // TODO WEBGPU. Triangle Fan Mode Fallback at buffer load time.
-                throw "TriangleFan is an unsupported fillmode in WebGPU";
-            default:
-                return WebGPUConstants.PrimitiveTopology.TriangleList;
-        }
-    }
-
-    private _getOpFunction(operation: Nullable<number>, defaultOp: GPUStencilOperation): GPUStencilOperation {
-        switch (operation) {
-            case Constants.KEEP:
-                return WebGPUConstants.StencilOperation.Keep;
-            case Constants.ZERO:
-                return WebGPUConstants.StencilOperation.Zero;
-            case Constants.REPLACE:
-                return WebGPUConstants.StencilOperation.Replace;
-            case Constants.INVERT:
-                return WebGPUConstants.StencilOperation.Invert;
-            case Constants.INCR:
-                return WebGPUConstants.StencilOperation.IncrementClamp;
-            case Constants.DECR:
-                return WebGPUConstants.StencilOperation.DecrementClamp;
-            case Constants.INCR_WRAP:
-                return WebGPUConstants.StencilOperation.IncrementWrap;
-            case Constants.DECR_WRAP:
-                return WebGPUConstants.StencilOperation.DecrementWrap;
-            default:
-                return defaultOp;
-        }
-    }
-
-    private _getDepthStencilStateDescriptor(): GPUDepthStencilStateDescriptor | undefined {
-        if (this._depthTextureFormat === undefined) {
-            return undefined;
-        }
-
-        const stencilFrontBack: GPUStencilStateFaceDescriptor = {
-            compare: WebGPUTextureHelper.GetCompareFunction(this._stencilState.stencilFunc),
-            depthFailOp: this._getOpFunction(this._stencilState.stencilOpDepthFail, WebGPUConstants.StencilOperation.Keep),
-            failOp: this._getOpFunction(this._stencilState.stencilOpStencilFail, WebGPUConstants.StencilOperation.Keep),
-            passOp: this._getOpFunction(this._stencilState.stencilOpStencilDepthPass, WebGPUConstants.StencilOperation.Replace)
-        };
-
-        return {
-            depthWriteEnabled: this.getDepthWrite(),
-            depthCompare: this.getDepthBuffer() ? WebGPUTextureHelper.GetCompareFunction(this.getDepthFunction()) : WebGPUConstants.CompareFunction.Always,
-            format: this._depthTextureFormat,
-            stencilFront: stencilFrontBack,
-            stencilBack: stencilFrontBack,
-            stencilReadMask: this._stencilState.stencilFuncMask,
-            stencilWriteMask: this._stencilState.stencilMask,
-        };
-    }
-
     /**
     /**
      * Set various states to the context
      * Set various states to the context
      * @param culling defines backface culling state
      * @param culling defines backface culling state
@@ -3349,48 +3275,6 @@ export class WebGPUEngineCache extends Engine {
         if (this._depthCullingState.frontFace !== frontFace || force) {
         if (this._depthCullingState.frontFace !== frontFace || force) {
             this._depthCullingState.frontFace = frontFace;
             this._depthCullingState.frontFace = frontFace;
         }
         }
-
-        this._cacheRenderPipeline.setState(culling, frontFace, cullFace);
-        this._cacheRenderPipeline.setDepthBiasSlopeScale(zOffset);
-    }
-
-    private _getFrontFace(): GPUFrontFace {
-        switch (this._depthCullingState.frontFace) {
-            case 1:
-                return WebGPUConstants.FrontFace.CCW;
-            default:
-                return WebGPUConstants.FrontFace.CW;
-        }
-    }
-
-    private _getCullMode(): GPUCullMode {
-        if (this._depthCullingState.cull === false) {
-            return WebGPUConstants.CullMode.None;
-        }
-
-        if (this._depthCullingState.cullFace === 2) {
-            return WebGPUConstants.CullMode.Front;
-        }
-        else {
-            return WebGPUConstants.CullMode.Back;
-        }
-    }
-
-    private _getRasterizationStateDescriptor(): GPURasterizationStateDescriptor {
-        return {
-            frontFace: this._getFrontFace(),
-            cullMode: this._getCullMode(),
-            depthBias: 0,
-            depthBiasClamp: 0,
-            depthBiasSlopeScale: this._depthCullingState.zOffset,
-        };
-    }
-
-    private _getWriteMask(): number {
-        if (this.__colorWrite) {
-            return WebGPUConstants.ColorWrite.All;
-        }
-        return 0;
     }
     }
 
 
     /**
     /**
@@ -3478,356 +3362,6 @@ export class WebGPUEngineCache extends Engine {
         this._cacheRenderPipeline.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);
         this._cacheRenderPipeline.setAlphaBlendFactors(this._alphaState._blendFunctionParameters, this._alphaState._blendEquationParameters);
     }
     }
 
 
-    private _getAphaBlendOperation(operation: Nullable<number>): GPUBlendOperation {
-        switch (operation) {
-            case 0x8006:
-                return WebGPUConstants.BlendOperation.Add;
-            case 0x800A:
-                return WebGPUConstants.BlendOperation.Subtract;
-            case 0x800B:
-                return WebGPUConstants.BlendOperation.ReverseSubtract;
-            case 0x8007:
-                return WebGPUConstants.BlendOperation.Min;
-            case 0x8008:
-                return WebGPUConstants.BlendOperation.Max;
-            default:
-                return WebGPUConstants.BlendOperation.Add;
-        }
-    }
-
-    private _getAphaBlendFactor(factor: Nullable<number>): GPUBlendFactor {
-        switch (factor) {
-            case 0:
-                return WebGPUConstants.BlendFactor.Zero;
-            case 1:
-                return WebGPUConstants.BlendFactor.One;
-            case 0x0300:
-                return WebGPUConstants.BlendFactor.SrcColor;
-            case 0x0301:
-                return WebGPUConstants.BlendFactor.OneMinusSrcColor;
-            case 0x0302:
-                return WebGPUConstants.BlendFactor.SrcAlpha;
-            case 0x0303:
-                return WebGPUConstants.BlendFactor.OneMinusSrcAlpha;
-            case 0x0304:
-                return WebGPUConstants.BlendFactor.DstAlpha;
-            case 0x0305:
-                return WebGPUConstants.BlendFactor.OneMinusDstAlpha;
-            case 0x0306:
-                return WebGPUConstants.BlendFactor.DstColor;
-            case 0x0307:
-                return WebGPUConstants.BlendFactor.OneMinusDstColor;
-            case 0x0308:
-                return WebGPUConstants.BlendFactor.SrcAlphaSaturated;
-            case 0x8001:
-                return WebGPUConstants.BlendFactor.BlendColor;
-            case 0x8002:
-                return WebGPUConstants.BlendFactor.OneMinusBlendColor;
-            case 0x8003:
-                return WebGPUConstants.BlendFactor.BlendColor;
-            case 0x8004:
-                return WebGPUConstants.BlendFactor.OneMinusBlendColor;
-            default:
-                return WebGPUConstants.BlendFactor.One;
-        }
-    }
-
-    private _getAphaBlendState(): GPUBlendDescriptor {
-        if (!this._alphaState.alphaBlend) {
-            return { };
-        }
-
-        return {
-            srcFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[2]),
-            dstFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[3]),
-            operation: this._getAphaBlendOperation(this._alphaState._blendEquationParameters[1]),
-        };
-    }
-
-    private _getColorBlendState(): GPUBlendDescriptor {
-        if (!this._alphaState.alphaBlend) {
-            return { };
-        }
-
-        return {
-            srcFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[0]),
-            dstFactor: this._getAphaBlendFactor(this._alphaState._blendFunctionParameters[1]),
-            operation: this._getAphaBlendOperation(this._alphaState._blendEquationParameters[0]),
-        };
-    }
-
-    private _getColorStateDescriptors(): GPUColorStateDescriptor[] {
-        const descriptors: GPUColorStateDescriptor[] = [];
-
-        const alphaBlend = this._getAphaBlendState();
-        const colorBlend = this._getColorBlendState();
-        const writeMask = this._getWriteMask();
-
-        if (this._currentRenderPassIsMRT()) {
-            const textureArray = this._currentRenderTarget!._textureArray!;
-            for (let i = 0; i < this._mrtAttachments.length; ++i) {
-                const index = this._mrtAttachments[i];
-                if (index > 0) {
-                    const mrtTexture = textureArray[index - 1];
-                    const gpuMRTWrapper = mrtTexture?._hardwareTexture as Nullable<WebGPUHardwareTexture>;
-                    descriptors.push({
-                        format: gpuMRTWrapper?.format ?? this._colorFormat,
-                        alphaBlend,
-                        colorBlend,
-                        writeMask,
-                    });
-                } else {
-                    descriptors.push(undefined as any); // TODO WEBGPU what to do when this._mrtAttachments[i] === 0? The corresponding texture should be bound as an "empty" texture
-                }
-            }
-        } else {
-            descriptors.push({
-                format: this._colorFormat,
-                alphaBlend,
-                colorBlend,
-                writeMask,
-            });
-        }
-
-        return descriptors;
-    }
-
-    private _getStages(): IWebGPURenderPipelineStageDescriptor {
-        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
-        return webgpuPipelineContext.stages!;
-    }
-
-    private _getVertexInputDescriptorFormat(vertexBuffer: VertexBuffer): GPUVertexFormat {
-        const kind = vertexBuffer.getKind();
-        const type = vertexBuffer.type;
-        const normalized = vertexBuffer.normalized;
-        const size = vertexBuffer.getSize();
-
-        switch (type) {
-            case VertexBuffer.BYTE:
-                switch (size) {
-                    case 1:
-                    case 2:
-                        return normalized ? WebGPUConstants.VertexFormat.Char2Norm : WebGPUConstants.VertexFormat.Char2;
-                    case 3:
-                    case 4:
-                        return normalized ? WebGPUConstants.VertexFormat.Char4Norm : WebGPUConstants.VertexFormat.Char4;
-                }
-                break;
-            case VertexBuffer.UNSIGNED_BYTE:
-                switch (size) {
-                    case 1:
-                    case 2:
-                        return normalized ? WebGPUConstants.VertexFormat.Uchar2Norm : WebGPUConstants.VertexFormat.Uchar2;
-                    case 3:
-                    case 4:
-                        return normalized ? WebGPUConstants.VertexFormat.Uchar4Norm : WebGPUConstants.VertexFormat.Uchar4;
-                }
-                break;
-            case VertexBuffer.SHORT:
-                switch (size) {
-                    case 1:
-                    case 2:
-                        return normalized ? WebGPUConstants.VertexFormat.Short2Norm : WebGPUConstants.VertexFormat.Short2;
-                    case 3:
-                    case 4:
-                        return normalized ? WebGPUConstants.VertexFormat.Short4Norm : WebGPUConstants.VertexFormat.Short4;
-                }
-                break;
-            case VertexBuffer.UNSIGNED_SHORT:
-                switch (size) {
-                    case 1:
-                    case 2:
-                        return normalized ? WebGPUConstants.VertexFormat.Ushort2Norm : WebGPUConstants.VertexFormat.Ushort2;
-                    case 3:
-                    case 4:
-                        return normalized ? WebGPUConstants.VertexFormat.Ushort4Norm : WebGPUConstants.VertexFormat.Ushort4;
-                }
-                break;
-            case VertexBuffer.INT:
-                switch (size) {
-                    case 1:
-                        return WebGPUConstants.VertexFormat.Int;
-                    case 2:
-                        return WebGPUConstants.VertexFormat.Int2;
-                    case 3:
-                        return WebGPUConstants.VertexFormat.Int3;
-                    case 4:
-                        return WebGPUConstants.VertexFormat.Int4;
-                }
-                break;
-            case VertexBuffer.UNSIGNED_INT:
-                switch (size) {
-                    case 1:
-                        return WebGPUConstants.VertexFormat.Uint;
-                    case 2:
-                        return WebGPUConstants.VertexFormat.Uint2;
-                    case 3:
-                        return WebGPUConstants.VertexFormat.Uint3;
-                    case 4:
-                        return WebGPUConstants.VertexFormat.Uint4;
-                }
-                break;
-            case VertexBuffer.FLOAT:
-                switch (size) {
-                    case 1:
-                        return WebGPUConstants.VertexFormat.Float;
-                    case 2:
-                        return WebGPUConstants.VertexFormat.Float2;
-                    case 3:
-                        return WebGPUConstants.VertexFormat.Float3;
-                    case 4:
-                        return WebGPUConstants.VertexFormat.Float4;
-                }
-                break;
-        }
-
-        throw new Error(`Invalid Format '${kind}' - type=${type}, normalized=${normalized}, size=${size}`);
-    }
-
-    private _getVertexInputDescriptor(topology: GPUPrimitiveTopology): GPUVertexStateDescriptor {
-        const descriptors: GPUVertexBufferLayoutDescriptor[] = [];
-        const effect = this._currentEffect!;
-        const attributes = effect.getAttributesNames();
-        for (var index = 0; index < attributes.length; index++) {
-            const location = effect.getAttributeLocation(index);
-
-            if (location >= 0) {
-                let  vertexBuffer = this._currentVertexBuffers![attributes[index]];
-                if (!vertexBuffer) {
-                    // In WebGL it's valid to not bind a vertex buffer to an attribute, but it's not valid in WebGPU
-                    // So we must bind a dummy buffer when we are not given one for a specific attribute
-                    vertexBuffer = this._emptyVertexBuffer;
-                }
-
-                const positionAttributeDescriptor: GPUVertexAttributeDescriptor = {
-                    shaderLocation: location,
-                    offset: 0, // not available in WebGL
-                    format: this._getVertexInputDescriptorFormat(vertexBuffer),
-                };
-
-                // TODO WEBGPU. Factorize the one with the same underlying buffer.
-                const vertexBufferDescriptor: GPUVertexBufferLayoutDescriptor = {
-                    arrayStride: vertexBuffer.byteStride,
-                    stepMode: vertexBuffer.getIsInstanced() ? WebGPUConstants.InputStepMode.Instance : WebGPUConstants.InputStepMode.Vertex,
-                    attributes: [positionAttributeDescriptor]
-                };
-
-               descriptors.push(vertexBufferDescriptor);
-            }
-        }
-
-        if (!this._currentIndexBuffer) {
-            return {
-                indexFormat: !this._indexFormatInRenderPass(topology) ? WebGPUConstants.IndexFormat.Uint32 : undefined,
-                vertexBuffers: descriptors
-            };
-        }
-
-        const inputStateDescriptor: GPUVertexStateDescriptor = {
-            vertexBuffers: descriptors
-        };
-
-        if (!this._indexFormatInRenderPass(topology)) {
-            inputStateDescriptor.indexFormat = this._currentIndexBuffer!.is32Bits ? WebGPUConstants.IndexFormat.Uint32 : WebGPUConstants.IndexFormat.Uint16;
-        }
-
-        return inputStateDescriptor;
-    }
-
-    private _getPipelineLayout(): GPUPipelineLayout {
-        const bindGroupLayouts: GPUBindGroupLayout[] = [];
-        const webgpuPipelineContext = this._currentEffect!._pipelineContext as WebGPUPipelineContext;
-
-        for (let i = 0; i < webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers.length; i++) {
-            const setDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i];
-            if (setDefinition === undefined) {
-                const entries: GPUBindGroupLayoutEntry[] = [];
-                const uniformsBindGroupLayout = this._device.createBindGroupLayout({
-                    entries,
-                });
-                bindGroupLayouts[i] = uniformsBindGroupLayout;
-                continue;
-            }
-
-            const entries: GPUBindGroupLayoutEntry[] = [];
-            for (let j = 0; j < setDefinition.length; j++) {
-                const bindingDefinition = webgpuPipelineContext.shaderProcessingContext.orderedUBOsAndSamplers[i][j];
-                if (bindingDefinition === undefined) {
-                    continue;
-                }
-
-                let visibility = 0;
-                if (bindingDefinition.usedInVertex) {
-                    visibility = visibility | WebGPUConstants.ShaderStage.Vertex;
-                }
-                if (bindingDefinition.usedInFragment) {
-                    visibility = visibility | WebGPUConstants.ShaderStage.Fragment;
-                }
-
-                if (bindingDefinition.isSampler) {
-                    entries.push({
-                        binding: j,
-                        visibility,
-                        type: bindingDefinition.isComparisonSampler ? WebGPUConstants.BindingType.ComparisonSampler : WebGPUConstants.BindingType.Sampler
-                    });
-                } else if (bindingDefinition.isTexture) {
-                    entries.push({
-                        binding: j,
-                        visibility,
-                        type: WebGPUConstants.BindingType.SampledTexture,
-                        viewDimension: bindingDefinition.textureDimension,
-                        textureComponentType: bindingDefinition.componentType,
-                        // TODO WEBGPU.
-                        // hasDynamicOffset?: boolean;
-                        // storageTextureFormat?: GPUTextureFormat;
-                        // minBufferBindingSize?: number;
-                    });
-                } else {
-                    entries.push({
-                        binding: j,
-                        visibility,
-                        type: WebGPUConstants.BindingType.UniformBuffer,
-                    });
-                }
-            }
-
-            if (entries.length > 0) {
-                const uniformsBindGroupLayout = this._device.createBindGroupLayout({
-                    entries,
-                });
-                bindGroupLayouts[i] = uniformsBindGroupLayout;
-            }
-        }
-
-        webgpuPipelineContext.bindGroupLayouts = bindGroupLayouts;
-        return this._device.createPipelineLayout({ bindGroupLayouts });
-    }
-
-    private _getRenderPipeline(topology: GPUPrimitiveTopology, createLayout = true): GPURenderPipeline {
-        this._counters.numPipelineDescriptorCreation++;
-
-        // Unsupported at the moment but needs to be extracted from the MSAA param.
-        const rasterizationStateDescriptor = this._getRasterizationStateDescriptor();
-        const depthStateDescriptor = this._getDepthStencilStateDescriptor();
-        const colorStateDescriptors = this._getColorStateDescriptors();
-        const stages = this._getStages();
-        const inputStateDescriptor = this._getVertexInputDescriptor(topology);
-        const pipelineLayout = createLayout ? this._getPipelineLayout() : undefined;
-
-        return this._device.createRenderPipeline({
-            sampleCount: this._currentRenderTarget ? this._currentRenderTarget.samples : this._mainPassSampleCount,
-            primitiveTopology: topology,
-            rasterizationState: rasterizationStateDescriptor,
-            depthStencilState: depthStateDescriptor,
-            colorStates: colorStateDescriptors,
-
-            ...stages,
-            vertexState: inputStateDescriptor,
-            layout: pipelineLayout,
-        });
-    }
-
     private _getVertexInputsToRender(): IWebGPUPipelineContextVertexInputsCache {
     private _getVertexInputsToRender(): IWebGPUPipelineContextVertexInputsCache {
         const effect = this._currentEffect!;
         const effect = this._currentEffect!;
 
 
@@ -4000,9 +3534,26 @@ export class WebGPUEngineCache extends Engine {
     private _setRenderPipeline(fillMode: number): void {
     private _setRenderPipeline(fillMode: number): void {
         const renderPass = this._bundleEncoder || this._getCurrentRenderPass();
         const renderPass = this._bundleEncoder || this._getCurrentRenderPass();
 
 
-        //const topology = this._getTopology(fillMode);
+        this._cacheRenderPipeline.setDepthCullingState(
+            !!this._depthCullingState.cull,
+            this._depthCullingState.frontFace ?? 2,
+            this._depthCullingState.cullFace ?? 1,
+            this._depthCullingState.zOffset,
+            this._depthCullingState.depthTest,
+            this._depthCullingState.depthMask,
+            this._depthCullingState.depthFunc
+        );
+
+        this._cacheRenderPipeline.setStencilState(
+            this._stencilState.stencilTest,
+            this._stencilState.stencilFunc,
+            this._stencilState.stencilOpDepthFail,
+            this._stencilState.stencilOpStencilDepthPass,
+            this._stencilState.stencilOpStencilFail,
+            this._stencilState.stencilFuncMask,
+            this._stencilState.stencilMask
+        );
 
 
-        //const pipeline = this._getRenderPipeline(topology);
         const pipeline = this._cacheRenderPipeline.getRenderPipeline(fillMode, this._currentEffect!, this._currentRenderTarget ? this._currentRenderTarget.samples : this._mainPassSampleCount);
         const pipeline = this._cacheRenderPipeline.getRenderPipeline(fillMode, this._currentEffect!, this._currentRenderTarget ? this._currentRenderTarget.samples : this._mainPassSampleCount);
         renderPass.setPipeline(pipeline);
         renderPass.setPipeline(pipeline);