stride3d/stride · error · NotSupportedException

Unsupported depth format

Error message

Unsupported depth format [{format}]

What it means

ComputeNonMSAADepthFormat converts a multisample-compatible depth-stencil PixelFormat into its non-MSAA depth equivalent and throws NotSupportedException for any depth format it does not know how to map. The switch only handles known depth/depth-stencil formats, so a new or unusual format reaching this code is unsupported by the forward renderer's depth handling.

Solutions

  1. Set the depth-stencil texture format to a standard supported value (D32_Float, D24_UNorm_S8_UInt, D16_UNorm, or the documented MSAA depth formats the renderer maps).
  2. Leave depth format selection to defaults unless you have a specific need; let the renderer/compositor pick the depth format.
  3. If you must support a new format, extend the switch in ComputeNonMSAADepthFormat with the mapping (patching the library).
  4. Log/inspect the incoming format at pipeline setup and clamp unsupported values before creating the render stage output.

Example fix

// before
renderStage.Output.DepthStencilState = new DepthStencilState { DepthBufferFormat = PixelFormat.R32G32_Typeless }; // unsupported
// after
renderStage.Output.DepthStencilState = new DepthStencilState { DepthBufferFormat = PixelFormat.D32_Float };
Defensive patterns

Strategy: validation

Validate before calling

PixelFormat[] supported = { PixelFormat.D32_Float, PixelFormat.D24_UNorm_S8_UInt, PixelFormat.D16_UNorm, PixelFormat.D32_Float_S8X24_UInt, PixelFormat.R32_Float_X8X24_Typeless };
bool isSupportedDepthFormat(PixelFormat f) => Array.IndexOf(supported, f) >= 0;

Try / catch

try { var fmt = ComputeNonMSAADepthFormat(format); } catch (NotSupportedException) { format = PixelFormat.D32_Float; }

Prevention

When it happens

Trigger: Configuring a RenderStage/render output with a depth buffer PixelFormat outside the supported set (e.g. an exotic typeless or combined format not in the switch) while using ForwardRenderer, causing the format mapping lookup to hit the default case.

Common situations: Custom GraphicsCompositor or render stage setups with hand-picked depth formats; migrating between graphics APIs/backends where a format is valid on one backend only; upgrading Stride when new PixelFormat values appear but the mapping wasn't extended.

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

Appendix: source

Thrown at sources/engine/Stride.Engine/Rendering/Compositing/ForwardRenderer.cs:457

                case PixelFormat.R32_Typeless:
                case PixelFormat.D32_Float:
                    result = PixelFormat.R32_Float;
                    break;

                // Note: for those formats we lose stencil buffer information during MSAA -> non-MSAA conversion
                case PixelFormat.R24G8_Typeless:
                case PixelFormat.D24_UNorm_S8_UInt:
                case PixelFormat.R24_UNorm_X8_Typeless:
                    result = PixelFormat.R32_Float;
                    break;
                case PixelFormat.R32G8X24_Typeless:
                case PixelFormat.D32_Float_S8X24_UInt:
                case PixelFormat.R32_Float_X8X24_Typeless:
                    result = PixelFormat.R32_Float;
                    break;

                default:
                    throw new NotSupportedException($"Unsupported depth format [{format}]");
            }

            return result;
        }

        /// <summary>
        /// Resolves the MSAA textures. Converts MSAA currentRenderTargets and currentDepthStencil into currentRenderTargetsNonMSAA and currentDepthStencilNonMSAA.
        /// </summary>
        /// <param name="drawContext">The draw context.</param>
        private void ResolveMSAA(RenderDrawContext drawContext)
        {
            // Resolve render targets
            CollectionsMarshal.SetCount(currentRenderTargetsNonMSAA, currentRenderTargets.Count);

            for (int index = 0; index < currentRenderTargets.Count; index++)
            {
                var input = currentRenderTargets[index];

View on GitHub (pinned to 96fad776d2)