stride3d/stride · error · NotSupportedException

Cannot initialize a read-only Depth-Stencil Buffer. Not…

Error message

Cannot initialize a read-only Depth-Stencil Buffer. Not supported on this device.

What it means

Read-only depth-stencil views (DsvFlags.ReadOnlyDepth / ReadOnlyStencil) require the device to support D3D12 features like OM SetRenderTargets with read-only DSV (TextureFlags-based read-only DSV support). IsDepthStencilReadOnlySupported(GraphicsDevice) checks this; when unsupported, creating a read-only depth-stencil texture throws in InitializeFromImpl.

Solutions

  1. Guard creation with Texture.IsDepthStencilReadOnlySupported(GraphicsDevice) and fall back to a plain DepthStencil flag set.
  2. Remove the read-only flag and bind the depth texture separately (unbind as DSV when sampling), or copy to a shader-resource texture.
  3. Upgrade hardware/driver or raise the required feature level so read-only DSVs are supported.

Example fix

// before
var flags = TextureFlags.DepthStencilReadOnly | TextureFlags.ShaderResource;
var tex = Texture.New2D(device, w, h, PixelFormat.D32.Float, flags);
// after
var flags = Texture.IsDepthStencilReadOnlySupported(device)
    ? TextureFlags.DepthStencilReadOnly | TextureFlags.ShaderResource
    : TextureFlags.DepthStencil;
var tex = Texture.New2D(device, w, h, PixelFormat.D32.Float, flags);
Defensive patterns

Strategy: fallback

Validate before calling

var flags = Texture.IsDepthStencilReadOnlySupported(device)
    ? TextureFlags.DepthStencilReadOnly | TextureFlags.ShaderResource
    : TextureFlags.DepthStencil | TextureFlags.ShaderResource;

Try / catch

try { return Texture.New2D(device, w, h, PixelFormat.D32.Float, readOnlyFlags); }
catch (NotSupportedException) { return Texture.New2D(device, w, h, PixelFormat.D32.Float, TextureFlags.DepthStencil | TextureFlags.ShaderResource); }

Prevention

When it happens

Trigger: Creating a Texture with TextureFlags.DepthStencilReadOnly (IsDepthStencilReadOnly true) on a device whose feature level/adapter does not support read-only DSVs.

Common situations: Shadow-map or cascaded-shadow renderers that sample depth while it is bound as depth-stencil; running on older hardware or WARP/software adapters; enabling read-only flags unconditionally without checking GraphicsDevice features.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D12/Texture.Direct3D12.cs:790

                {
                    depthStencilViewDescription.ViewDimension = DsvDimension.Texture2Darray;
                    depthStencilViewDescription.Texture2DArray.ArraySize = (uint) ArraySize;
                    depthStencilViewDescription.Texture2DArray.FirstArraySlice = 0;
                    depthStencilViewDescription.Texture2DArray.MipSlice = 0;
                }
                else // Regular Texture (2D)
                {
                    depthStencilViewDescription.ViewDimension = DsvDimension.Texture2D;
                    depthStencilViewDescription.Texture2D.MipSlice = 0;
                }

                if (MultisampleCount > MultisampleCount.None)
                    depthStencilViewDescription.ViewDimension = DsvDimension.Texture2Dms;

                if (IsDepthStencilReadOnly)
                {
                    if (!IsDepthStencilReadOnlySupported(GraphicsDevice))
                        throw new NotSupportedException("Cannot initialize a read-only Depth-Stencil Buffer. Not supported on this device.");

                    // Create a Depth-Stencil View on this 2D Texture
                    depthStencilViewDescription.Flags = DsvFlags.ReadOnlyDepth;
                    if (HasStencil)
                        depthStencilViewDescription.Flags |= DsvFlags.ReadOnlyStencil;
                }

                var descriptorHandle = GraphicsDevice.DepthStencilViewAllocator.Allocate(1);

                NativeDevice.CreateDepthStencilView(NativeResource, in depthStencilViewDescription, descriptorHandle);
                return descriptorHandle;
            }

            //
            // Gets a specific Unordered Access View from the Texture.
            //
            CpuDescriptorHandle GetUnorderedAccessView(ViewType viewType, int arrayOrDepthSlice, int mipIndex)
            {

View on GitHub (pinned to 96fad776d2)