Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Add SoA raytracer as a CQ test for Intel hardware intrinsic
Browse files Browse the repository at this point in the history
  • Loading branch information
FeiPengIntel committed Jul 11, 2018
1 parent 7baedfd commit 72804ec
Show file tree
Hide file tree
Showing 25 changed files with 1,439 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using System.Runtime.Intrinsics.X86;
using static System.Runtime.Intrinsics.X86.Avx;
using System.Runtime.Intrinsics;
internal class Camera
{

public Camera(VectorPacket256 pos, VectorPacket256 forward, VectorPacket256 up, VectorPacket256 right) { Pos = pos; Forward = forward; Up = up; Right = right; }

public VectorPacket256 Pos;
public VectorPacket256 Forward;
public VectorPacket256 Up;
public VectorPacket256 Right;

public static Camera Create(VectorPacket256 pos, VectorPacket256 lookAt)
{
VectorPacket256 forward = (lookAt - pos).Normalize();
VectorPacket256 down = new VectorPacket256(SetAllVector256<float>(0), SetAllVector256<float>(-1), SetAllVector256<float>(0));
VectorPacket256 right = SetAllVector256<float>(1.5f) * VectorPacket256.CrossProduct(forward, down).Normalize();
VectorPacket256 up = SetAllVector256<float>(1.5f) * VectorPacket256.CrossProduct(forward, right).Normalize();

return new Camera(pos, forward, up, right);
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using System.Runtime.Intrinsics;
using static System.Runtime.Intrinsics.X86.Avx;
using System.Runtime.CompilerServices;

internal struct Color
{
public float R {get; private set;}
public float G {get; private set;}
public float B {get; private set;}

public static readonly Color Background = new Color(0, 0, 0);

public Color(float _r, float _g, float _b)
{
R = _r;
G = _g;
B = _b;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using static System.Runtime.Intrinsics.X86.Avx;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics;

using ColorPacket256 = VectorPacket256;

internal static class ColorPacket256Helper
{
public static Int32RGBPacket256 ConvertToIntRGB(this VectorPacket256 colors)
{
var one = SetAllVector256<float>(1.0f);
var max = SetAllVector256<float>(255.0f);

var rsMask = Compare(colors.Xs, one, FloatComparisonMode.GreaterThanOrderedNonSignaling);
var gsMask = Compare(colors.Ys, one, FloatComparisonMode.GreaterThanOrderedNonSignaling);
var bsMask = Compare(colors.Zs, one, FloatComparisonMode.GreaterThanOrderedNonSignaling);

var rs = BlendVariable(colors.Xs, one, rsMask);
var gs = BlendVariable(colors.Ys, one, gsMask);
var bs = BlendVariable(colors.Zs, one, bsMask);

var rsInt = ConvertToVector256Int32(Multiply(rs, max));
var gsInt = ConvertToVector256Int32(Multiply(gs, max));
var bsInt = ConvertToVector256Int32(Multiply(bs, max));

return new Int32RGBPacket256(rsInt, gsInt, bsInt);
}

public static ColorPacket256 Times(ColorPacket256 left, ColorPacket256 right)
{
return new VectorPacket256(Multiply(left.Xs, right.Xs), Multiply(left.Ys, right.Ys), Multiply(left.Zs, right.Zs));
}

public static ColorPacket256 BackgroundColor = new ColorPacket256(SetZeroVector256<float>());
public static ColorPacket256 DefaultColor = new ColorPacket256(SetZeroVector256<float>());
}

internal struct Int32RGBPacket256
{
public Vector256<int> Rs;
public Vector256<int> Gs;
public Vector256<int> Bs;

public Int32RGBPacket256(Vector256<int> _rs, Vector256<int> _gs, Vector256<int>_bs)
{
Rs = _rs;
Gs = _gs;
Bs = _bs;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using static System.Runtime.Intrinsics.X86.Avx;
using static System.Runtime.Intrinsics.X86.Avx2;
using System.Runtime.Intrinsics.X86;
using System.Runtime.Intrinsics;
using System.Runtime.CompilerServices;
using System;

internal struct Intersections
{
public Vector256<float> Distances;
public Vector256<int> ThingIndeces;

public static readonly Vector256<float> NullDistance = SetAllVector256<float>(float.MaxValue);
public static readonly Vector256<int> NullIndex = SetAllVector256<int>(-1);

public Intersections(Vector256<float> dis, Vector256<int> things)
{
Distances = dis;
ThingIndeces = things;
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool AllNullIntersections()
{
return AllNullIntersections(Distances);
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool AllNullIntersections(Vector256<float> dis)
{
var cmp = Compare(dis, NullDistance, FloatComparisonMode.EqualOrderedNonSignaling);
var zero = SetZeroVector256<int>();
var mask = Avx2.CompareEqual(zero, zero);
return TestC(cmp, StaticCast<int, float>(mask));
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

internal class Light
{
public Vector Pos;
public Color Color;

public Light(Vector pos, Color color) { Pos = pos; Color = color; }
public LightPacket256 ToPacket256() { return new LightPacket256(Pos, Color);}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using System.Runtime.CompilerServices;
using ColorPacket256 = VectorPacket256;

internal class LightPacket256
{
public VectorPacket256 Positions;
public ColorPacket256 Colors;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public LightPacket256(Vector pos, Color col)
{
Positions = new VectorPacket256(pos.X, pos.Y, pos.Z);
Colors = new ColorPacket256(col.R, col.G, col.B);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using System.Runtime.Intrinsics;

internal abstract class ObjectPacket256
{
public Surface Surface {get; private set;}
public abstract Vector256<float> Intersect(RayPacket256 rayPacket256);
public abstract VectorPacket256 Normals(VectorPacket256 pos);

public ObjectPacket256(Surface surface)
{
Surface = surface;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
//

using System.Collections.Generic;
using System.Diagnostics;

namespace System.Collections.Concurrent
{
/// <summary>Provides a thread-safe object pool.</summary>
/// <typeparam name="T">Specifies the type of the elements stored in the pool.</typeparam>
[DebuggerDisplay("Count={Count}")]
[DebuggerTypeProxy(typeof(IProducerConsumerCollection_DebugView<>))]
public sealed class ObjectPool<T> : ProducerConsumerCollectionBase<T>
{
private readonly Func<T> _generator;

/// <summary>Initializes an instance of the ObjectPool class.</summary>
/// <param name="generator">The function used to create items when no items exist in the pool.</param>
public ObjectPool(Func<T> generator) : this(generator, new ConcurrentQueue<T>()) { }

/// <summary>Initializes an instance of the ObjectPool class.</summary>
/// <param name="generator">The function used to create items when no items exist in the pool.</param>
/// <param name="collection">The collection used to store the elements of the pool.</param>
public ObjectPool(Func<T> generator, IProducerConsumerCollection<T> collection)
: base(collection)
{
if (generator == null) throw new ArgumentNullException("generator");
_generator = generator;
}

/// <summary>Adds the provided item into the pool.</summary>
/// <param name="item">The item to be added.</param>
public void PutObject(T item) { base.TryAdd(item); }

/// <summary>Gets an item from the pool.</summary>
/// <returns>The removed or created item.</returns>
/// <remarks>If the pool is empty, a new item will be created and returned.</remarks>
public T GetObject()
{
T value;
return base.TryTake(out value) ? value : _generator();
}

/// <summary>Clears the object pool, returning all of the data that was in the pool.</summary>
/// <returns>An array containing all of the elements in the pool.</returns>
public T[] ToArrayAndClear()
{
var items = new List<T>();
T value;
while (base.TryTake(out value)) items.Add(value);
return items.ToArray();
}

protected override bool TryAdd(T item)
{
PutObject(item);
return true;
}

protected override bool TryTake(out T item)
{
item = GetObject();
return true;
}
}
}
Loading

0 comments on commit 72804ec

Please sign in to comment.