stride3d/stride · error · ArgumentException

Expecting a Buffer supporting UAV

Error message

Expecting a Buffer supporting UAV

What it means

CommandList.ClearReadWrite(Buffer, Vector4) clears a GPU buffer via its Unordered Access View (UAV). On Direct3D12, the throw fires when buffer.NativeUnorderedAccessView.Ptr is 0, meaning the buffer was never created with the UnorderedAccess flag, so no UAV exists to clear through. The library refuses silently proceeding because the native clear would corrupt or do nothing.

Solutions

  1. Recreate the Buffer with BufferFlags.UnorderedAccess (e.g. Buffer.New(graphicsDevice, size, stride, BufferFlags.UnorderedAccess)).
  2. If the buffer must serve multiple roles, include UnorderedAccess together with the other needed flags (StructuredBuffer | UnorderedAccess).
  3. Guard the call: only call ClearReadWrite when buffer.NativeUnorderedAccessView.Ptr != 0.

Example fix

// before
var buffer = Buffer.New(device, 1024, 16, BufferFlags.StructuredBuffer);
commandList.ClearReadWrite(buffer, Vector4.Zero); // throws

// after
var buffer = Buffer.New(device, 1024, 16, BufferFlags.StructuredBuffer | BufferFlags.UnorderedAccess);
commandList.ClearReadWrite(buffer, Vector4.Zero);
Defensive patterns

Strategy: validation

Validate before calling

if (buffer == null) throw new ArgumentNullException(nameof(buffer));
if (buffer.NativeUnorderedAccessView.Ptr == 0)
    throw new InvalidOperationException("Buffer must be created with BufferFlags.UnorderedAccess before ClearReadWrite");

Type guard

bool SupportsBufferUav(Buffer b) => b != null && b.NativeUnorderedAccessView.Ptr != 0;

Try / catch

try
{
    commandList.ClearReadWrite(buffer, value);
}
catch (ArgumentException ex) when (ex.ParamName == nameof(buffer))
{
    // recreate buffer with BufferFlags.UnorderedAccess or skip clear
}

Prevention

When it happens

Trigger: Calling CommandList.ClearReadWrite(buffer, value) with a Buffer whose NativeUnorderedAccessView.Ptr == 0 — i.e. the Buffer was created without BufferFlags.UnorderedAccess (e.g. a default vertex/index/staging buffer).

Common situations: Reusing a plain structured buffer for a compute shader read/write counter or output without the UAV flag; passing a staging or copy-source buffer because it happens to be the right size; D3D11-era code ported to D3D12 where UAV-capable buffers were implicit.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Graphics/Direct3D12/CommandList.Direct3D12.cs:1216

            currentCommandList.NativeCommandList.ClearRenderTargetView(renderTarget.NativeRenderTargetView, ref clearColorFloats,
                                                                        NumRects: 0, in nullRect);
            RecordDebugCounter(DebugCounterKind.Clear);
        }

        /// <summary>
        ///   Clears a Read-Write Buffer.
        /// </summary>
        /// <param name="buffer">The Buffer to clear. It must have been created with read-write / unordered access flags.</param>
        /// <param name="value">The value to use to clear the Buffer.</param>
        /// <exception cref="ArgumentNullException"><paramref name="buffer"/> is <see langword="null"/>.</exception>
        /// <exception cref="ArgumentException"><paramref name="buffer"/> must support Unordered Access.</exception>
        public void ClearReadWrite(Buffer buffer, Vector4 value)
        {
            ArgumentNullException.ThrowIfNull(buffer);

            if (buffer.NativeUnorderedAccessView.Ptr == 0)
                throw new ArgumentException("Expecting a Buffer supporting UAV", nameof(buffer));

            ResourceBarrierTransition(buffer, BarrierLayout.UnorderedAccess);
            FlushResourceBarriers();

            var cpuHandle = buffer.NativeUnorderedAccessView;
            var gpuHandle = GetGpuDescriptorHandle(cpuHandle);

            scoped ref SilkBox2I nullRect = ref NullRef<SilkBox2I>();
            scoped ref var clearValue = ref value.AsSpan<Vector4, float>()[0];

            currentCommandList.NativeCommandList.ClearUnorderedAccessViewFloat(gpuHandle, cpuHandle, buffer.NativeResource,
                                                                               ref clearValue, NumRects: 0, in nullRect);
            RecordDebugCounter(DebugCounterKind.Clear);
        }

        /// <summary>
        ///   Clears a Read-Write Buffer.
        /// </summary>

View on GitHub (pinned to 96fad776d2)