stride3d/stride · error · NotImplementedException

SurfaceRotation ' ' is not supported on Direct3D presenters.

Error message

SurfaceRotation '{SurfaceRotation}' is not supported on Direct3D presenters.

What it means

Direct3D swapchain creation does not accept a non-Identity SurfaceRotation, because DXGI (and the D3D runtime) handle display rotation transparently at the presentation level. Stride throws NotImplementedException in CreateSwapChain to fail fast rather than silently mis-rotating the back buffer. Only SurfaceRotation.Identity is valid for D3D presenters.

Solutions

  1. Set Description.SurfaceRotation to SurfaceRotation.Identity when targeting Direct3D presenters.
  2. Guard the rotation assignment so it is only applied on platforms whose presenters honor it (e.g. #if !STRIDE_PLATFORM_DIRECT3D or a runtime backend check).
  3. If the display appears incorrectly rotated, fix it via OS/display-driver orientation settings or DXGI, not the presenter description.

Example fix

// before
var description = new GraphicsPresenterDescription { SurfaceRotation = rotationFromSensor };
var presenter = new SwapChainGraphicsPresenter(device, description);
// after
var description = new GraphicsPresenterDescription { SurfaceRotation = device.IsDirect3D ? SurfaceRotation.Identity : rotationFromSensor };
var presenter = new SwapChainGraphicsPresenter(device, description);
Defensive patterns

Strategy: validation

Validate before calling

if (description.SurfaceRotation != SurfaceRotation.Identity && /* D3D backend */ OperatingSystem.IsWindows())
    throw new InvalidOperationException("Direct3D presenters require SurfaceRotation.Identity");

Type guard

bool IsD3DRotationValid(SurfaceRotation rotation) => rotation == SurfaceRotation.Identity;

Try / catch

try { presenter = new SwapChainGraphicsPresenter(device, desc); }
catch (NotImplementedException) { desc.SurfaceRotation = SurfaceRotation.Identity; presenter = new SwapChainGraphicsPresenter(device, desc); }

Prevention

When it happens

Trigger: Creating a SwapChainGraphicsPresenter (or recreating it after device loss via OnRecreated) on a Direct3D backend while Description.SurfaceRotation is set to anything other than SurfaceRotation.Identity.

Common situations: Porting code written for Vulkan/OpenGL presenters (where rotation must be handled manually) to Windows/UWP Direct3D; copying presenter initialization code across platforms; a shared cross-platform code path that sets SurfaceRotation based on device orientation.

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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D/SwapChainGraphicsPresenter.Direct3D.cs:560

                childTexture.InitializeFrom(parentTexture: DepthStencilBuffer, in childTexture.ViewDescription);
            }
        }

        /// <summary>
        ///   Creates or reinitializes the Swap-Chain with the current configuration.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        ///   <see cref="PresentationParameters.DeviceWindowHandle"/> is <see langword="null"/> or
        ///   the <see cref="WindowHandle.Handle"/> is invalid or zero.
        /// </exception>
        private void CreateSwapChain()
        {
            if (Description.DeviceWindowHandle is null)
                throw new InvalidOperationException("DeviceWindowHandle cannot be null");

            // D3D presenters don't honor SurfaceRotation (DXGI handles rotation transparently).
            if (SurfaceRotation != SurfaceRotation.Identity)
                throw new NotImplementedException($"SurfaceRotation '{SurfaceRotation}' is not supported on Direct3D presenters.");

#if STRIDE_PLATFORM_UWP
            CreateSwapChainForUWP();
#else
            CreateSwapChainForWindows();
#endif
        }

#if STRIDE_PLATFORM_UWP
        /// <summary>
        ///   Creates or reinitializes the Swap-Chain on the Universal Windows Platform (UWP).
        /// </summary>
        private void CreateSwapChainForUWP()
        {
            // Use two buffers to enable flip effect
            bufferCount = 2;

            // UWP does automatic sizing of the Swap-Chain based on the XAML element containing it.

View on GitHub (pinned to 96fad776d2)