stride3d/stride · error · NotImplementedException

Copy region from staging texture is not supported yet

Error message

Copy region from staging texture is not supported yet

What it means

This NotImplementedException is thrown by CopyRegion when the source texture has GraphicsResourceUsage.Staging. The D3D12 backend only implements full-resource copy for staging sources; copying a specific region out of a staging texture is not implemented yet in the Direct3D12 CommandList.

Solutions

  1. Use Copy with a full-resource copy (or CommandList.Copy that supports staging sources) and do region handling on the CPU after mapping the staging texture.
  2. Recreate the source as a non-staging (Default/Immutable) texture if a GPU-side region copy is genuinely needed, copying staging data in first via Copy.
  3. Restructure so the staging texture already contains only the region of interest, sized exactly to the region.
  4. Patch the engine: implement the staging-source path via Map/UpdateSubresource instead of a GPU copy, or file/track the upstream TODO.

Example fix

// before
commandList.CopyRegion(sourceStagingTexture, 0, region, destTexture, 0);
// after
commandList.Copy(sourceStagingTexture, destTexture); // full copy only, then Map dest staging side
cpuData = ExtractRegionOnCPU(destTexture, region);
Defensive patterns

Strategy: validation

Validate before calling

if (sourceTexture.Usage == GraphicsResourceUsage.Staging)
{
    // region copy unsupported on D3D12: use full Copy or CPU path
    commandList.Copy(sourceTexture, destinationTexture);
}
else
{
    commandList.CopyRegion(sourceTexture, 0, region, destinationTexture, 0);
}

Type guard

static bool SupportsRegionCopy(Texture t) => t.Usage != GraphicsResourceUsage.Staging;

Prevention

When it happens

Trigger: Calling CommandList.CopyRegion(source, ...) where source.Usage == GraphicsResourceUsage.Staging on the Direct3D12 backend. The full-resource Copy path handles staging; the region overload does not.

Common situations: Copying a sub-region between staging textures during CPU<->GPU data staging workflows; porting D3D11 code that used CopySubresourceRegion with staging textures; reading back part of a large staging texture instead of the whole thing.

Related errors


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

Appendix: source

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

            //
            // 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)
                {
                    throw new NotImplementedException("Copy region from staging texture is not supported yet");
                }

                var srcRegion = new TextureCopyLocation
                {
                    PResource = source.NativeResource,
                    Type = TextureCopyType.SubresourceIndex,
                    SubresourceIndex = (uint) sourceSubResourceIndex
                };

                SkipInit(out TextureCopyLocation destRegion);

                if (destinationTexture.Usage == GraphicsResourceUsage.Staging)
                {
                    var destinationParent = destinationTexture.ParentTexture ?? destinationTexture;

                    SkipInit(out PlacedSubresourceFootprint footprint);
                    uint numRows = 0;
                    ulong rowSizeInBytes = 0;

View on GitHub (pinned to 96fad776d2)