stride3d/stride · error · InvalidOperationException

Cannot copy data between Buffers and Textures.

Error message

Cannot copy data between Buffers and Textures.

What it means

The region-copy method (CopyRegion) supports only same-type pairs: Texture->Texture and Buffer->Buffer. Any other combination, including copying between a Buffer and a Texture, throws InvalidOperationException because the D3D12 region-copy path in this method does not implement cross-type conversions.

Solutions

  1. Use the dedicated CopyCommandList.Copy(Buffer, Texture) / Copy(Texture, Buffer) methods for cross-type transfers.
  2. Call CopyRegion only with matching types (both Buffers or both Textures).
  3. Add a runtime type check before dispatching to CopyRegion.

Example fix

// before
commandList.CopyRegion(buffer, texture, sourceRegion); // throws

// after
if (source is Texture t && destination is Texture d)
    commandList.CopyRegion(t, d, sourceRegion);
else
    commandList.CopyCommandList.Copy(source, destination); // cross-type path
Defensive patterns

Strategy: type-guard

Validate before calling

bool ok = (source is Buffer && destination is Buffer) || (source is Texture && destination is Texture);
if (!ok) throw new InvalidOperationException("CopyRegion supports only Buffer->Buffer or Texture->Texture");

Type guard

static bool IsSameKindPair(GraphicsResource s, GraphicsResource d) =>
    s.GetType() == d.GetType() && (s is Buffer || s is Texture);

Try / catch

try
{
    commandList.CopyRegion(source, destination, region);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Buffers and Textures"))
{
    commandList.CopyCommandList.Copy(source, destination); // cross-type transfer
}

Prevention

When it happens

Trigger: Calling CommandList.CopyRegion(source, destination, ...) with source/destination of mixed types (Buffer vs Texture) or otherwise unmatched GraphicsResource types.

Common situations: Trying to upload a buffer into a texture region or read back a texture region into a buffer via CopyRegion; generic copy helpers passing arbitrary resources; argument order/type mistakes.

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/d1e4ce036634898b. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs:1737

        ///     <see cref="CopyRegion"/> only supports copy; it doesn't support any stretch, color key, or blend.
        ///   </para>
        /// </remarks>
        public void CopyRegion(GraphicsResource source, int sourceSubResourceIndex, ResourceRegion? sourceRegion,
                               GraphicsResource destination, int destinationSubResourceIndex, int dstX = 0, int dstY = 0, int dstZ = 0)
        {
            RecordDebugCounter(DebugCounterKind.Copy);

            if (source is Texture sourceTexture &&
                destination is Texture destinationTexture)
            {
                CopyBetweenTextures(sourceTexture, destinationTexture);
            }
            else if (source is Buffer sourceBuffer &&
                     destination is Buffer destinationBuffer)
            {
                CopyBetweenBuffers(sourceBuffer, destinationBuffer);
            }
            else throw new InvalidOperationException("Cannot copy data between Buffers and Textures.");

            //
            // Copies a region from a Texture to another Texture.
            //
            void CopyBetweenTextures(Texture sourceTexture, Texture destinationTexture)
            {
                if (sourceTexture.Usage == GraphicsResourceUsage.Staging &&
                    destinationTexture.Usage == GraphicsResourceUsage.Staging)
                {
                    throw new NotImplementedException("Copy region of staging resources is not supported yet"); // TODO: Implement copy region for staging resources
                }

                ResourceBarrierTransition(source, BarrierLayout.CopySource);
                ResourceBarrierTransition(destination, BarrierLayout.CopyDest);
                FlushResourceBarriers();

                if (sourceTexture.Usage == GraphicsResourceUsage.Staging)
                {

View on GitHub (pinned to 96fad776d2)