{"record":{"id":"f0c776faef3bd420","repo":"BabylonJS/Babylon.js","slug":"updatewrappednativetexture-new-handle-layer-count","errorCode":null,"errorMessage":"updateWrappedNativeTexture: new handle layer count (${newLayerCount}) must match the wrapped texture's layer count (${oldLayerCount}).","messagePattern":"updateWrappedNativeTexture: new handle layer count \\((.+?)\\) must match the wrapped texture's layer count \\((.+?)\\)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Engines/thinNativeEngine.pure.ts","lineNumber":2172,"sourceCode":"     * @param texture defines the new native texture handle to wrap\r\n     */\r\n    public updateWrappedNativeTexture(internalTexture: InternalTexture, texture: NativeTexture): void {\r\n        if (internalTexture.source !== InternalTextureSource.External) {\r\n            throw new Error(\"updateWrappedNativeTexture: target InternalTexture was not produced by wrapNativeTexture.\");\r\n        }\r\n\r\n        const newWidth = this._engine.getTextureWidth(texture);\r\n        const newHeight = this._engine.getTextureHeight(texture);\r\n        if (newWidth !== internalTexture.baseWidth || newHeight !== internalTexture.baseHeight) {\r\n            throw new Error(\r\n                `updateWrappedNativeTexture: new handle dimensions (${newWidth}x${newHeight}) must match the wrapped texture's dimensions (${internalTexture.baseWidth}x${internalTexture.baseHeight}).`\r\n            );\r\n        }\r\n        if (this._engine.getTextureLayerCount) {\r\n            const newLayerCount = this._engine.getTextureLayerCount(texture);\r\n            const oldLayerCount = internalTexture.is2DArray ? internalTexture.depth : 1;\r\n            if (newLayerCount !== oldLayerCount) {\r\n                throw new Error(`updateWrappedNativeTexture: new handle layer count (${newLayerCount}) must match the wrapped texture's layer count (${oldLayerCount}).`);\r\n            }\r\n        }\r\n\r\n        // Pre-validate before mutating any state so a thrown precondition leaves the InternalTexture untouched.\r\n        // Note: rtWrapper.texture only returns _textures[0]; walk every attachment to catch the multi-RT case where\r\n        // the wrapped texture is at index > 0.\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (!rtWrapper.textures?.includes(internalTexture)) {\r\n                continue;\r\n            }\r\n            if (rtWrapper.isMulti) {\r\n                throw new Error(\"updateWrappedNativeTexture: wrapped texture is part of a multi render-target; not supported. Dispose and re-wrap.\");\r\n            }\r\n            if (rtWrapper._depthStencilTexture) {\r\n                // After a DisableRendering / EnableRendering cycle the bgfx framebuffer + the depth/stencil texture's\r\n                // bgfx handle are both stale. Rebuilding the depth/stencil texture from the wrapper's stored settings\r\n                // is feasible but non-trivial; v1 rejects and asks the caller to dispose + re-wrap.\r\n                throw new Error(\"updateWrappedNativeTexture: wrapped texture's render-target wrapper has a depth/stencil texture; not supported. Dispose and re-wrap.\");\r","sourceCodeStart":2154,"sourceCodeEnd":2190,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Engines/thinNativeEngine.pure.ts#L2154-L2190","documentation":"updateWrappedNativeTexture validates layer counts: if the wrapped texture is a 2D array its depth is compared against the new handle's layer count (via getTextureLayerCount); for non-array textures the expected count is 1. A mismatch throws because repointing would silently change the texture's effective layering.","triggerScenarios":"Swapping in a native texture handle whose layer/array-layer count differs from the wrapped texture (e.g. replacing a 6-layer array or cube-derived handle with a single-layer texture, or vice versa).","commonSituations":"Exchanging a texture array between passes with different layer counts; wrapping cube/2D-array textures then updating with a plain 2D handle.","solutions":["Ensure the replacement native texture is created with the same layer count (same array size/cube structure).","Dispose and re-wrap via wrapNativeTexture when the layer structure genuinely changes.","Skip the update path entirely for array textures and recreate dependent pipelines/framebuffers instead."],"exampleFix":"// before\nengine.updateWrappedNativeTexture(wrappedArray, singleLayerTex);\n\n// after\nconst newWrapped = engine.wrapNativeTexture(arrayTex, w, h, { layers: oldDepth });","handlingStrategy":"validation","validationCode":"const newLayers = engine._engine.getTextureLayerCount?.(newNativeTex) ?? 1;\nconst expectedLayers = wrapped.is2DArray ? wrapped.depth : 1;\nif (newLayers !== expectedLayers) throw new Error(`Layer count mismatch: ${newLayers} vs ${expectedLayers}`);","typeGuard":null,"tryCatchPattern":"try {\n  engine.updateWrappedNativeTexture(wrapped, newNativeTex);\n} catch (e) {\n  if (e.message.includes(\"layer count\")) {\n    wrapped.dispose();\n    wrapped = engine.wrapNativeTexture(newNativeTex, w, h, sampling, ...);\n  } else throw e;\n}","preventionTips":["Avoid texture arrays entirely on Babylon Native (also rejected by createRawTexture).","Match cube/array structure when creating replacement native textures.","Document layer-count invariants wherever native handles are exchanged between systems."],"tags":["native","texture-wrapping","layer-count"],"backgroundTag":"texture-size-mismatch","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}