From 5c0127fe9443f234e14ce79c07ac4174eb462bc9 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Thu, 12 Feb 2026 16:18:19 +0000 Subject: [PATCH 1/4] [FIX] Refresh texture state when mipmaps toggles Update Texture#mipmaps to recalculate mip levels and mark min filter parameters dirty when toggled, so runtime mipmap changes apply immediately without requiring unrelated texture edits. Co-authored-by: Cursor --- src/platform/graphics/texture.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/platform/graphics/texture.js b/src/platform/graphics/texture.js index ce0c787e902..2fcc891d1f3 100644 --- a/src/platform/graphics/texture.js +++ b/src/platform/graphics/texture.js @@ -674,11 +674,13 @@ class Texture { Debug.warn('Texture#mipmaps: mipmap property cannot be changed on an integer texture, will remain false', this); } else { this._mipmaps = v; - } + this._updateNumLevel(); + this.propertyChanged(TEXPROPERTY_MIN_FILTER); - if (v) { - this._needsMipmapsUpload = true; - this.device?.texturesToUpload?.add(this); + if (v) { + this._needsMipmapsUpload = true; + this.device?.texturesToUpload?.add(this); + } } } } From 170b2901d4eccf1476014155ddc846fb08017764 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Thu, 12 Feb 2026 16:32:49 +0000 Subject: [PATCH 2/4] Update src/platform/graphics/texture.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- src/platform/graphics/texture.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/graphics/texture.js b/src/platform/graphics/texture.js index 2fcc891d1f3..33cb5d35aff 100644 --- a/src/platform/graphics/texture.js +++ b/src/platform/graphics/texture.js @@ -677,7 +677,7 @@ class Texture { this._updateNumLevel(); this.propertyChanged(TEXPROPERTY_MIN_FILTER); - if (v) { + if (this._mipmaps && this._numLevels > 1) { this._needsMipmapsUpload = true; this.device?.texturesToUpload?.add(this); } From 91efa9ebae4372d8bd58688d4587eb7280078347 Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Thu, 12 Feb 2026 16:37:16 +0000 Subject: [PATCH 3/4] [FIX] Handle mipmaps toggle edge cases Base mip upload scheduling on effective mipmap state after _updateNumLevel, and recreate array texture storage when mip level count changes to keep immutable GPU allocation in sync. Co-authored-by: Cursor --- src/platform/graphics/texture.js | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/platform/graphics/texture.js b/src/platform/graphics/texture.js index 33cb5d35aff..297d6e893ba 100644 --- a/src/platform/graphics/texture.js +++ b/src/platform/graphics/texture.js @@ -673,13 +673,24 @@ class Texture { } else if (isIntegerPixelFormat(this._format)) { Debug.warn('Texture#mipmaps: mipmap property cannot be changed on an integer texture, will remain false', this); } else { + const oldMipmaps = this._mipmaps; + const oldNumLevels = this._numLevels; + this._mipmaps = v; this._updateNumLevel(); - this.propertyChanged(TEXPROPERTY_MIN_FILTER); - if (this._mipmaps && this._numLevels > 1) { - this._needsMipmapsUpload = true; - this.device?.texturesToUpload?.add(this); + // Changing mip count on array textures requires re-creating immutable storage. + if (this.array && this._numLevels !== oldNumLevels) { + this.recreateImpl(); + } else if (this._mipmaps !== oldMipmaps) { + this.propertyChanged(TEXPROPERTY_MIN_FILTER); + + if (this._mipmaps) { + this._needsMipmapsUpload = true; + this.device?.texturesToUpload?.add(this); + } else { + this._needsMipmapsUpload = false; + } } } } From c5cf72a1545bd7d9d1ec19f483687eee266c803e Mon Sep 17 00:00:00 2001 From: Will Eastcott Date: Thu, 12 Feb 2026 16:39:20 +0000 Subject: [PATCH 4/4] Add s to _updateNumLevel --- src/platform/graphics/texture.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/platform/graphics/texture.js b/src/platform/graphics/texture.js index 297d6e893ba..34c8efa8ceb 100644 --- a/src/platform/graphics/texture.js +++ b/src/platform/graphics/texture.js @@ -265,7 +265,7 @@ class Texture { if (options.numLevels !== undefined) { this._numLevels = options.numLevels; } - this._updateNumLevel(); + this._updateNumLevels(); this._minFilter = options.minFilter ?? FILTER_LINEAR_MIPMAP_LINEAR; this._magFilter = options.magFilter ?? FILTER_LINEAR; @@ -376,7 +376,7 @@ class Texture { this._width = Math.floor(width); this._height = Math.floor(height); this._depth = Math.floor(depth); - this._updateNumLevel(); + this._updateNumLevels(); // re-create the implementation this.impl = device.createTextureImpl(this); @@ -421,7 +421,7 @@ class Texture { this.renderVersionDirty = this.device.renderVersion; } - _updateNumLevel() { + _updateNumLevels() { const maxLevels = this.mipmaps ? TextureUtils.calcMipLevelsCount(this.width, this.height) : 1; const requestedLevels = this._numLevelsRequested; @@ -677,7 +677,7 @@ class Texture { const oldNumLevels = this._numLevels; this._mipmaps = v; - this._updateNumLevel(); + this._updateNumLevels(); // Changing mip count on array textures requires re-creating immutable storage. if (this.array && this._numLevels !== oldNumLevels) {