stride3d/stride · error · NotSupportedException

AlphaLoadMode. not supported for DDS (source…

Error message

AlphaLoadMode.{alphaLoadMode} not supported for DDS (source premultiplied-state cannot be reliably determined).

What it means

Thrown when decoding a DDS texture with an alphaLoadMode other than AlphaLoadMode.Preserve. DDS files carry no portable flag indicating whether plain BGRA/RGBA payloads are premultiplied (the premul state only exists in the DX10 extension), so the library cannot safely convert between straight and premultiplied alpha and refuses any explicit mode.

Solutions

  1. Pass AlphaLoadMode.Preserve when loading DDS textures.
  2. If conversion is truly required, decode with Preserve and convert explicitly after checking the DX10 HeaderDXT10 AlphaMode when present (or the asset's known convention).
  3. Catch NotSupportedException around the decode and fall back to Preserve.

Example fix

// before
var tex = DdsLoader.Load(stream, AlphaLoadMode.Premultiplied);

// after
var tex = DdsLoader.Load(stream, AlphaLoadMode.Preserve);
// premul conversion must be done explicitly after decode, not requested here
Defensive patterns

Strategy: validation

Validate before calling

if (alphaLoadMode != AlphaLoadMode.Preserve)
    throw new NotSupportedException("DDS decode requires AlphaLoadMode.Preserve; convert premul state explicitly after decode");

Type guard

bool IsDdsSafeAlphaMode(AlphaLoadMode m) => m == AlphaLoadMode.Preserve;

Try / catch

try { tex = DdsLoader.Load(stream, alphaLoadMode); }
catch (NotSupportedException e) when (e.Message.Contains("AlphaLoadMode"))
{
    tex = DdsLoader.Load(stream, AlphaLoadMode.Preserve);
    tex = ApplyAlphaConversion(tex, alphaLoadMode); // explicit, caller-verified
}

Prevention

When it happens

Trigger: Calling a DDS decode API that accepts an AlphaLoadMode parameter with AlphaLoadMode.Straight or AlphaLoadMode.Premultiplied instead of AlphaLoadMode.Preserve.

Common situations: Porting loader code that used PNG/TGA-style alpha handling and passing an explicit alpha mode to the DDS loader; pipeline code that globally sets a premultiplied-alpha policy for all texture formats.

Related errors


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

Appendix: source

Thrown at sources/engine/Stride.Foundation/Graphics/DDSHelper.cs:1000

        /// </summary>
        /// <param name="pSource"></param>
        /// <param name="size"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        public static unsafe Image LoadFromDDSMemory(IntPtr pSource, int size, bool makeACopy, GCHandle? handle, AlphaLoadMode alphaLoadMode)
        {
            var flags = makeACopy ? DDSFlags.CopyMemory : DDSFlags.None;

            ConversionFlags convFlags;
            ImageDescription mdata;
            // If the memory pointed is not a DDS memory, return null.
            if (!DecodeDDSHeader(pSource, size, flags, out mdata, out convFlags))
                return null;

            // DDS has no portable premul-state flag for plain BGRA/RGBA payloads (DX10 AlphaLoadMode is
            // only present in the HeaderDXT10 extension), so we can't safely convert blindly.
            if (alphaLoadMode != AlphaLoadMode.Preserve)
                throw new NotSupportedException($"AlphaLoadMode.{alphaLoadMode} not supported for DDS (source premultiplied-state cannot be reliably determined).");

            int offset = sizeof (uint) + Unsafe.SizeOf<DDS.Header>();
            if ((convFlags & ConversionFlags.DX10) != 0)
                offset += Unsafe.SizeOf<DDS.HeaderDXT10>();

            var pal8 = (uint*) 0;
            if ((convFlags & ConversionFlags.Pal8) != 0)
            {
                pal8 = (uint*) ((byte*) (pSource) + offset);
                offset += (256 * sizeof (uint));
            }

            if (size < offset)
                throw new InvalidOperationException();

            var image = CreateImageFromDDS(pSource, offset, size - offset, mdata, (flags & DDSFlags.LegacyDword) != 0 ? Image.PitchFlags.LegacyDword : Image.PitchFlags.None, convFlags, pal8, handle);
            return image;
        }

View on GitHub (pinned to 96fad776d2)