stride3d/stride · error · NotSupportedException

Only array of 2D textures are currently supported as output

Error message

Only array of 2D textures are currently supported as output

What it means

RadiancePrefilteringGGX.DrawCore throws NotSupportedException when PrefilteredRadiance is null, is not a 2D-array or cube texture view, or has ArraySize != 6. The prefiltering compute shader writes one mip chain per face of a 6-slice array (cubemap faces), so only that output layout is implemented.

Solutions

  1. Create PrefilteredRadiance as a Texture2D with ArraySize = 6 (or a cubemap), bindable as unordered access.
  2. Ensure the texture is allocated and assigned to the PrefilteredRadiance property before render.
  3. Check ViewDimension is Texture2D or TextureCube and ArraySize equals 6.

Example fix

// before
var output = Texture.New2D(device, 256, 256, PixelFormat.Rgba16_Float, TextureFlags.ShaderResource); // plain 2D
prefilter.PrefilteredRadiance = output;
// after
var output = Texture.New2D(device, 256, 256, PixelFormat.Rgba16_Float, TextureFlags.ShaderResource | TextureFlags.UnorderedAccess, mipCount: 9, arraySize: 6);
prefilter.PrefilteredRadiance = output;
Defensive patterns

Strategy: validation

Validate before calling

if (output == null || (output.ViewDimension != TextureDimension.Texture2D && output.ViewDimension != TextureDimension.TextureCube) || output.ArraySize != 6)
    throw new InvalidOperationException("PrefilteredRadiance must be a 2D array/cube texture with ArraySize == 6");

Type guard

bool IsValidPrefilterOutput(Texture t) => t != null && (t.ViewDimension == TextureDimension.Texture2D || t.ViewDimension == TextureDimension.TextureCube) && t.ArraySize == 6;

Try / catch

try { prefilter.Render(context); }
catch (NotSupportedException ex) { Log.Error("PrefilteredRadiance must be a 6-slice 2D array (cubemap) texture.", ex); }

Prevention

When it happens

Trigger: Assigning a plain Texture2D, a texture array with a slice count other than 6, or leaving PrefilteredRadiance null before rendering the prefilter.

Common situations: Creating the prefiltered target as an ordinary 2D texture instead of a 6-slice array; generating the output texture with a mip-count/ArraySize mismatch; forgetting to allocate the output texture before running IBL prefiltering.

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

Appendix: source

Thrown at sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGX.cs:76

        {
            get { return samplingsCount; }
            set
            {
                if (value > 1024)
                    throw new ArgumentOutOfRangeException("value");

                if (!MathUtil.IsPow2(value))
                    throw new ArgumentException("The provided value should be a power of 2");

                samplingsCount = Math.Max(1, value);
            }
        }

        protected override void DrawCore(RenderDrawContext context)
        {
            var output = PrefilteredRadiance;
            if (output == null || (output.ViewDimension != TextureDimension.Texture2D && output.ViewDimension != TextureDimension.TextureCube) || output.ArraySize != 6)
                throw new NotSupportedException("Only array of 2D textures are currently supported as output");

            if (!output.IsUnorderedAccess || output.IsRenderTarget)
                throw new NotSupportedException("Only non-rendertarget unordered access textures are supported as output");

            var input = RadianceMap;
            if (input == null || input.Dimension != TextureDimension.TextureCube)
                throw new NotSupportedException("Only cubemaps are currently supported as input");

            var roughness = 0f;
            var faceCount = output.ArraySize;
            var levelSize = new Int2(output.Width, output.Height);
            var mipCount = MipmapGenerationCount == 0 ? output.MipLevelCount : MipmapGenerationCount;

            for (int l = 0; l < mipCount; l++)
            {
                if (l == 0 && DoNotFilterHighestLevel && input.Width >= output.Width)
                {
                    var inputLevel = MathUtil.Log2(input.Width / output.Width);

View on GitHub (pinned to 96fad776d2)