{"record":{"id":"6fadcc066b80cdf4","repo":"BabylonJS/Babylon.js","slug":"updatewrappednativetexture-wrapped-texture-s-rend","errorCode":null,"errorMessage":"updateWrappedNativeTexture: wrapped texture's render-target wrapper has a depth/stencil texture; not supported. Dispose and re-wrap.","messagePattern":"updateWrappedNativeTexture: wrapped texture's render-target wrapper has a depth/stencil texture; not supported\\. Dispose and re-wrap\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Engines/thinNativeEngine.pure.ts","lineNumber":2190,"sourceCode":"                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\n            }\r\n        }\r\n\r\n        internalTexture._hardwareTexture = new NativeHardwareTexture(texture, this._engine);\r\n        internalTexture.isReady = true;\r\n        this.updateTextureSamplingMode(internalTexture.samplingMode, internalTexture);\r\n\r\n        // Rebuild the framebuffer of any render-target wrapper holding this wrapped texture as its color attachment.\r\n        // After a DisableRendering / EnableRendering cycle the bgfx framebuffer handle is stale; the consumer-supplied\r\n        // new texture is the moment we have a fresh handle to rebuild against.\r\n        for (const rtWrapper of this._renderTargetWrapperCache) {\r\n            if (rtWrapper.texture !== internalTexture) {\r\n                continue;\r\n            }\r\n            const nativeRTWrapper = rtWrapper as NativeRenderTargetWrapper;\r\n            // NativeRenderTargetWrapper._framebuffer setter releases the old framebuffer before assigning,\r\n            // so no manual _releaseFramebufferObjects call is needed (and would double-delete the handle).\r\n            nativeRTWrapper._framebuffer = this._engine.createFrameBuffer(\r","sourceCodeStart":2172,"sourceCodeEnd":2208,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Engines/thinNativeEngine.pure.ts#L2172-L2208","documentation":"updateWrappedNativeTexture refuses to update a wrapped texture whose render-target wrapper owns a depth/stencil texture. After a DisableRendering/EnableRendering cycle the bgfx framebuffer and depth/stencil handle become stale, and rebuilding them during the swap is non-trivial, so v1 rejects and asks the caller to dispose and re-wrap.","triggerScenarios":"engine.updateWrappedNativeTexture called on a texture whose rtWrapper._depthStencilTexture is set (render target created with a depth/stencil attachment), even if it is not an MRT.","commonSituations":"Offscreen scene rendering with depth testing where the color texture's native handle is recreated externally (e.g. by a compositor) and the code tries to repoint it.","solutions":["Dispose the render-target wrapper (which frees the depth/stencil texture) and recreate it with the new native texture via wrapNativeTexture.","Create the render target without a depth/stencil attachment if depth is not needed.","Avoid DisableRendering/EnableRendering cycles around the wrapped RT, or recreate state after such cycles."],"exampleFix":"// before\nengine.updateWrappedNativeTexture(rt.texture, newNativeTex); // rt has depth/stencil\n\n// after\nrtWrapper.dispose();\nrtWrapper = engine.createRenderTargetTexture(size, { ...opts, texture: engine.wrapNativeTexture(newNativeTex, w, h, ...) });","handlingStrategy":"validation","validationCode":"const rt = engine._renderTargetWrapperCache.find(rt => rt.textures?.includes(wrapped));\nif (rt && rt._depthStencilTexture) throw new Error(\"RT wrapper has depth/stencil texture; dispose and re-wrap required.\");","typeGuard":null,"tryCatchPattern":"try {\n  engine.updateWrappedNativeTexture(wrapped, newNativeTex);\n} catch (e) {\n  if (e.message.includes(\"depth/stencil\")) {\n    rtWrapper.dispose();\n    rtWrapper = createRTWithWrappedTexture(newNativeTex, depthStencilOpts);\n  } else throw e;\n}","preventionTips":["Prefer dispose + recreate for render targets that own depth/stencil attachments.","Create depth-less render targets when hot-swapping color textures is required.","Be aware DisableRendering/EnableRendering cycles stale bgfx handles; rebuild RTs around them."],"tags":["native","texture-wrapping","depth-stencil","unsupported"],"backgroundTag":"unsupported-mrt-update","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}