stride3d/stride · error · NotSupportedException
Only non-rendertarget unordered access textures are…
Error message
Only non-rendertarget unordered access textures are supported as output
What it means
RadiancePrefilteringGGX.DrawCore throws NotSupportedException when the PrefilteredRadiance texture is not bindable as an unordered access view (IsUnorderedAccess false) or is a render target (IsRenderTarget true). The prefilter runs a compute shader that writes directly into the output mips, which requires UAV binding; render-target textures are rejected.
Solutions
- Create the output texture with TextureFlags.UnorderedAccess and without RenderTarget.
- Recreate the texture: flags = TextureFlags.ShaderResource | TextureFlags.UnorderedAccess.
- Verify no code path enables RenderTarget on the prefiltered radiance texture.
Example fix
// before var output = Texture.New2D(device, 256, 256, fmt, TextureFlags.RenderTarget | TextureFlags.ShaderResource); // after var output = Texture.New2D(device, 256, 256, fmt, TextureFlags.UnorderedAccess | TextureFlags.ShaderResource, arraySize: 6);
Defensive patterns
Strategy: validation
Validate before calling
if (!output.IsUnorderedAccess || output.IsRenderTarget)
throw new InvalidOperationException("PrefilteredRadiance must be a non-rendertarget UAV texture"); Type guard
bool IsUsableUav(Texture t) => t != null && t.IsUnorderedAccess && !t.IsRenderTarget;
Try / catch
try { prefilter.Render(context); }
catch (NotSupportedException ex) { Log.Error("Prefilter output must be a UAV texture and not a render target.", ex); } Prevention
- Always pass TextureFlags.UnorderedAccess (never RenderTarget) when creating the prefilter output.
- Don't reuse backbuffer or render-target textures as compute outputs.
- Check texture flags in the IBL setup step rather than at render time.
When it happens
Trigger: Creating the output texture with only TextureFlags.ShaderResource (no UnorderedAccess), or with flags that make it a render target, then running the prefilter.
Common situations: Reusing a backbuffer/render-target texture as the prefiltered output; forgetting the UnorderedAccess flag when creating the target; graphics device/feature level that restricts simultaneous UAV use.
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
- Only array of 2D textures are currently supported as output
- Entity factories should create single entity. Creating a…
- Replace, Move and Reset are not supported on this…
- Unsupported depth format
- Custom strides is not supported with packed PixelFormats
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/5e415a3bb0284b71.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Rendering/Rendering/ComputeEffect/GGXPrefiltering/RadiancePrefilteringGGX.cs:79
{
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);
for (int f = 0; f < 6; f++)
{
var inputSubresource = inputLevel + f * input.MipLevelCount;View on GitHub (pinned to 96fad776d2)