stride3d/stride · error · NotSupportedException

Cannot swap texture views; only root textures can be…

Error message

Cannot swap texture views; only root textures can be swapped.

What it means

Thrown by the internal Texture.Swap method when either texture is a view (has a ParentTexture). Swapping only exchanges root-level descriptions and view descriptions, so swapping views is unsupported and would corrupt state. Raised as NotSupportedException.

Solutions

  1. Swap only root textures; obtain the root via the texture's ParentTexture chain and swap those.
  2. Skip the swap when ParentTexture is not null, or recreate independent textures instead of views.
  3. If you need view-like behavior, swap the underlying root textures and recreate views afterwards.

Example fix

// before
textureView.Swap(otherView); // both are views
// after
var rootA = textureView.ParentTexture ?? textureView;
var rootB = otherView.ParentTexture ?? otherView;
rootA.Swap(rootB);
Defensive patterns

Strategy: type-guard

Validate before calling

if (texture.ParentTexture is not null || other.ParentTexture is not null)
    throw new InvalidOperationException("Swap requires root textures");

Type guard

bool IsRootTexture(Texture t) => t is not null && t.ParentTexture is null;

Prevention

When it happens

Trigger: Calling Texture.Swap(other) where this.ParentTexture or other.ParentTexture is non-null, i.e. either texture was created as a view (e.g. via CreateView / slice / mip view) of another texture.

Common situations: Engine-level code that swaps render targets hitting a view (e.g. a cube-face or array-slice view); pooling textures where a pooled item was registered as a view.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/97abc402d52a1786. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Texture.cs:1822

            ArgumentNullException.ThrowIfNull(textureData);

            // Check that the textureData has the correct size for the Texture's data
            Image.ComputePitch(format, width, height, out var rowPitch, out var slicePitch, out _, out _);

            if (sizeof(TData) * textureData.Length != (slicePitch * depth))
                throw new ArgumentException("Invalid Texture data length", nameof(textureData));

            return new DataBox(fixedPointer, rowPitch, slicePitch);
        }

        /// <summary>
        ///   Swaps the Texture's internal data with another Texture.
        /// </summary>
        /// <param name="other">The other Texture.</param>
        internal void Swap([NotNull] Texture other)
        {
            if (ParentTexture is not null || other.ParentTexture is not null)
                throw new NotSupportedException("Cannot swap texture views; only root textures can be swapped.");

            (textureDescription, other.textureDescription) = (other.textureDescription, textureDescription);
            (textureViewDescription, other.textureViewDescription) = (other.textureViewDescription, textureViewDescription);
            (mipmapDescriptions, other.mipmapDescriptions) = (other.mipmapDescriptions, mipmapDescriptions);
            (fullQualitySize, other.fullQualitySize) = (other.fullQualitySize, fullQualitySize);

            (other.ViewWidth, ViewWidth) = (ViewWidth, other.ViewWidth);
            (other.ViewHeight, ViewHeight) = (ViewHeight, other.ViewHeight);
            (other.ViewDepth, ViewDepth) = (ViewDepth, other.ViewDepth);
            (other.SizeInBytes, SizeInBytes) = (SizeInBytes, other.SizeInBytes);

            SwapInternal(other);
        }

        /// <summary>
        ///   Computes the bounds of a Texture View based on the View type, which determines what sub-Resources
        ///   the Texture View can access.
        /// </summary>

View on GitHub (pinned to 96fad776d2)