Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Png/Zlib/Adler32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static uint Calculate(uint adler, ReadOnlySpan<byte> buffer)
}

#if SUPPORTS_RUNTIME_INTRINSICS
if (Sse3.IsSupported && buffer.Length >= MinBufferSize)
if (Ssse3.IsSupported && buffer.Length >= MinBufferSize)
{
return CalculateSse(adler, buffer);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we also rename CalculateSse to CalculateSsse?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say no. It’s still an iteration of SSE technology.

}
Expand Down
48 changes: 47 additions & 1 deletion tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
// Licensed under the Apache License, Version 2.0.

// ReSharper disable InconsistentNaming
using System.Diagnostics;
using System.IO;
using System.Linq;

#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics.X86;
#endif
using Microsoft.DotNet.RemoteExecutor;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
using SixLabors.ImageSharp.Tests.TestUtilities;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;

using Xunit;
Expand Down Expand Up @@ -529,6 +534,47 @@ public void Encode_WorksWithDiscontiguousBuffers<TPixel>(TestImageProvider<TPixe
}
}

[Theory]
[WithTestPatternImages(100, 100, PixelTypes.Rgba32)]
public void EncodeWorksWithoutSsse3Intrinsics<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel>
{
static void RunTest(string providerDump)
{
TestImageProvider<TPixel> provider =
BasicSerializer.Deserialize<TestImageProvider<TPixel>>(providerDump);
#if SUPPORTS_RUNTIME_INTRINSICS
Assert.False(Ssse3.IsSupported);
#endif

foreach (PngInterlaceMode interlaceMode in InterlaceMode)
{
TestPngEncoderCore(
provider,
PngColorType.Rgb,
PngFilterMethod.Adaptive,
PngBitDepth.Bit8,
interlaceMode,
appendPixelType: true,
appendPngColorType: true);
}
}

string providerDump = BasicSerializer.Serialize(provider);

var processStartInfo = new ProcessStartInfo();
processStartInfo.Environment[TestEnvironment.Features.EnableSSE3] = TestEnvironment.Features.Off;

RemoteExecutor.Invoke(
RunTest,
providerDump,
new RemoteInvokeOptions
{
StartInfo = processStartInfo
})
.Dispose();
}

private static void TestPngEncoderCore<TPixel>(
TestImageProvider<TPixel> provider,
PngColorType pngColorType,
Expand Down
34 changes: 34 additions & 0 deletions tests/ImageSharp.Tests/TestUtilities/TestEnvironment.Features.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.

namespace SixLabors.ImageSharp.Tests
{
public static partial class TestEnvironment
{
internal static class Features
{
public const string On = "1";
public const string Off = "0";

public const string EnableAES = "COMPlus_EnableAES";
public const string EnableAVX = "COMPlus_EnableAVX";
public const string EnableAVX2 = "COMPlus_EnableAVX2";
public const string EnableBMI1 = "COMPlus_EnableBMI1";
public const string EnableBMI2 = "COMPlus_EnableBMI2";
public const string EnableFMA = "COMPlus_EnableFMA";
public const string EnableHWIntrinsic = "COMPlus_EnableHWIntrinsic";
public const string EnableIncompleteISAClass = "COMPlus_EnableIncompleteISAClass";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one isn't a production switch.

For the others, there is a rough hierarchy they follow:

  • EnableHWIntrinsic
    • EnableSSE
      • EnableSSE2
        • EnableAES
        • EnablePCLMULQDQ
        • EnableSSE3
          • EnableSSSE3
            • EnableSSE41
              • EnableSSE42
                • EnablePOPCNT
                • EnableAVX
                  • EnableFMA
                  • EnableAVX2
    • EnableBMI1
    • EnableBMI2
    • EnableLZCNT

FeatureSIMD ends up impacting all SIMD support (including System.Numerics) but not things like LZCNT, BMI1, or BMI2
EnableSSE3_4 is a legacy switch that exists for compat and is basically the same as EnableSSE3

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hierarchy basically means disabling SSE (EnableSSE=0) will also disable everything below it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah lovely. I'll reference that. I intend on doing more intrinsics work in the near future.

public const string EnableLZCNT = "COMPlus_EnableLZCNT";
public const string EnablePCLMULQDQ = "COMPlus_EnablePCLMULQDQ";
public const string EnablePOPCNT = "COMPlus_EnablePOPCNT";
public const string EnableSSE = "COMPlus_EnableSSE";
public const string EnableSSE2 = "COMPlus_EnableSSE2";
public const string EnableSSE3 = "COMPlus_EnableSSE3";
public const string EnableSSE3_4 = "COMPlus_EnableSSE3_4";
public const string EnableSSE41 = "COMPlus_EnableSSE41";
public const string EnableSSE42 = "COMPlus_EnableSSE42";
public const string EnableSSSE3 = "COMPlus_EnableSSSE3";
public const string FeatureSIMD = "COMPlus_FeatureSIMD";
}
}
}