Compare commits
2 Commits
e9d3e695ba
...
fef20f05b7
| Author | SHA1 | Date | |
|---|---|---|---|
| fef20f05b7 | |||
| 27569e9eb5 |
@@ -78,3 +78,21 @@ public interface IUnsafeHashCollection<T> : IDisposable
|
|||||||
/// <param name="option">Specifies allocation options that may affect how memory is managed during the resize operation.</param>
|
/// <param name="option">Specifies allocation options that may affect how memory is managed during the resize operation.</param>
|
||||||
void Resize(int newSize, AllocationOption option);
|
void Resize(int newSize, AllocationOption option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IUnsafeBitSet
|
||||||
|
{
|
||||||
|
int Count
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NextSetBit(int startIndex);
|
||||||
|
void SetBit(int index);
|
||||||
|
void ClearBit(int index);
|
||||||
|
bool IsSet(int index);
|
||||||
|
|
||||||
|
void SetAll();
|
||||||
|
void ClearAll();
|
||||||
|
|
||||||
|
Span<uint> AsSpan();
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using Misaki.HighPerformance.LowLevel.Buffer;
|
using Misaki.HighPerformance.LowLevel.Buffer;
|
||||||
|
using Misaki.HighPerformance.LowLevel.Collections.Contracts;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
@@ -33,7 +34,7 @@ internal class UnsafeBitSetDebugView
|
|||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerTypeProxy(typeof(UnsafeBitSetDebugView))]
|
[DebuggerTypeProxy(typeof(UnsafeBitSetDebugView))]
|
||||||
public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
public unsafe struct UnsafeBitSet : IUnsafeBitSet, IDisposable, IEquatable<UnsafeBitSet>
|
||||||
{
|
{
|
||||||
public ref struct Iterator
|
public ref struct Iterator
|
||||||
{
|
{
|
||||||
@@ -54,9 +55,9 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal const int _BIT_SIZE = sizeof(uint) * 8 - 1; // 31
|
internal const int BIT_SIZE = sizeof(uint) * 8 - 1; // 31
|
||||||
internal const int _INDEX_SIZE = 5; // log_2(BitSize + 1)
|
internal const int INDEX_SIZE = 5; // log_2(BitSize + 1)
|
||||||
internal const int _MASK = (1 << 5) - 1; // 0x1F, the mask to get the bit index inside a uint
|
internal const int MASK = (1 << 5) - 1; // 0x1F, the mask to get the bit index inside a uint
|
||||||
internal static readonly int s_padding = Vector<uint>.Count; // The padding used for vectorization, the amount of uints required for being vectorized basically
|
internal static readonly int s_padding = Vector<uint>.Count; // The padding used for vectorization, the amount of uints required for being vectorized basically
|
||||||
|
|
||||||
private UnsafeArray<uint> _bits;
|
private UnsafeArray<uint> _bits;
|
||||||
@@ -76,7 +77,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the total number of bits represented by the current instance.
|
/// Gets the total number of bits represented by the current instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly int Count => _bits.Count << _INDEX_SIZE;
|
public readonly int Count => _bits.Count << INDEX_SIZE;
|
||||||
|
|
||||||
public readonly bool IsCreated => _bits.IsCreated;
|
public readonly bool IsCreated => _bits.IsCreated;
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
/// <param name="option">The allocation option.</param>
|
/// <param name="option">The allocation option.</param>
|
||||||
public UnsafeBitSet(int minimalLength, AllocationHandle handle, AllocationOption option = AllocationOption.None)
|
public UnsafeBitSet(int minimalLength, AllocationHandle handle, AllocationOption option = AllocationOption.None)
|
||||||
{
|
{
|
||||||
var uints = (minimalLength >> _INDEX_SIZE) + int.Sign(minimalLength & _BIT_SIZE);
|
var uints = (minimalLength >> INDEX_SIZE) + int.Sign(minimalLength & BIT_SIZE);
|
||||||
var length = RoundToPadding(uints);
|
var length = RoundToPadding(uints);
|
||||||
|
|
||||||
_bits = new UnsafeArray<uint>(length, handle, option);
|
_bits = new UnsafeArray<uint>(length, handle, option);
|
||||||
@@ -113,12 +114,12 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
_bits.CopyFrom(bits);
|
_bits.CopyFrom(bits);
|
||||||
|
|
||||||
_highestBit = 0;
|
_highestBit = 0;
|
||||||
_max = _bits.Count * (_BIT_SIZE + 1) - 1; // Calculate the maximum index in use
|
_max = _bits.Count * (BIT_SIZE + 1) - 1; // Calculate the maximum index in use
|
||||||
for (var i = 0; i < _bits.Count; i++)
|
for (var i = 0; i < _bits.Count; i++)
|
||||||
{
|
{
|
||||||
if (_bits[i] != 0)
|
if (_bits[i] != 0)
|
||||||
{
|
{
|
||||||
_highestBit = Math.Max(_highestBit, i * (_BIT_SIZE + 1) + BitOperations.Log2(_bits[i]) + 1);
|
_highestBit = Math.Max(_highestBit, i * (BIT_SIZE + 1) + BitOperations.Log2(_bits[i]) + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -137,7 +138,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int RequiredLength(int id)
|
public static int RequiredLength(int id)
|
||||||
{
|
{
|
||||||
return (id >> _INDEX_SIZE) + int.Sign(id & _BIT_SIZE);
|
return (id >> INDEX_SIZE) + int.Sign(id & BIT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@@ -155,13 +156,13 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public readonly bool IsSet(int index)
|
public readonly bool IsSet(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _INDEX_SIZE;
|
var b = index >> INDEX_SIZE;
|
||||||
if (b >= _bits.Count)
|
if (b >= _bits.Count)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (_bits[b] & 1 << (index & _BIT_SIZE)) != 0;
|
return (_bits[b] & 1 << (index & BIT_SIZE)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -172,7 +173,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void SetBit(int index)
|
public void SetBit(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _INDEX_SIZE;
|
var b = index >> INDEX_SIZE;
|
||||||
if (b >= _bits.Count)
|
if (b >= _bits.Count)
|
||||||
{
|
{
|
||||||
_bits.Resize(index);
|
_bits.Resize(index);
|
||||||
@@ -181,8 +182,8 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
|
|
||||||
// Track highest set bit
|
// Track highest set bit
|
||||||
_highestBit = Math.Max(_highestBit, index);
|
_highestBit = Math.Max(_highestBit, index);
|
||||||
_max = _highestBit / (_BIT_SIZE + 1) + 1;
|
_max = _highestBit / (BIT_SIZE + 1) + 1;
|
||||||
_bits[b] |= 1u << (index & _BIT_SIZE);
|
_bits[b] |= 1u << (index & BIT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -192,13 +193,13 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void ClearBit(int index)
|
public void ClearBit(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _INDEX_SIZE;
|
var b = index >> INDEX_SIZE;
|
||||||
if (b >= _bits.Count)
|
if (b >= _bits.Count)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_bits[b] &= ~(1u << (index & _BIT_SIZE));
|
_bits[b] &= ~(1u << (index & BIT_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -209,8 +210,8 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
{
|
{
|
||||||
_bits.AsSpan().Fill(0xffffffff);
|
_bits.AsSpan().Fill(0xffffffff);
|
||||||
|
|
||||||
_highestBit = _bits.Count * (_BIT_SIZE + 1) - 1;
|
_highestBit = _bits.Count * (BIT_SIZE + 1) - 1;
|
||||||
_max = _highestBit / (_BIT_SIZE + 1) + 1;
|
_max = _highestBit / (BIT_SIZE + 1) + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -229,21 +230,21 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly int NextSetBit(int startIndex)
|
public readonly int NextSetBit(int startIndex)
|
||||||
{
|
{
|
||||||
var wordIndex = startIndex >> _BIT_SIZE;
|
var wordIndex = startIndex >> BIT_SIZE;
|
||||||
if (wordIndex >= _bits.Count)
|
if (wordIndex >= _bits.Count)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask off bits below startIndex in the first word:
|
// Mask off bits below startIndex in the first word:
|
||||||
var word = _bits[wordIndex] & ~0u << (startIndex & _MASK);
|
var word = _bits[wordIndex] & ~0u << (startIndex & MASK);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (word != 0)
|
if (word != 0)
|
||||||
{
|
{
|
||||||
// get the least-significant set bit
|
// get the least-significant set bit
|
||||||
var bit = BitOperations.TrailingZeroCount(word);
|
var bit = BitOperations.TrailingZeroCount(word);
|
||||||
return (wordIndex << _BIT_SIZE) + bit;
|
return (wordIndex << BIT_SIZE) + bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
wordIndex++;
|
wordIndex++;
|
||||||
@@ -259,7 +260,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
public void Resize(int minimalLength, AllocationOption option = AllocationOption.None)
|
public void Resize(int minimalLength, AllocationOption option = AllocationOption.None)
|
||||||
{
|
{
|
||||||
var oldSize = _bits.Count;
|
var oldSize = _bits.Count;
|
||||||
var uints = (minimalLength >> _INDEX_SIZE) + int.Sign(minimalLength & _BIT_SIZE);
|
var uints = (minimalLength >> INDEX_SIZE) + int.Sign(minimalLength & BIT_SIZE);
|
||||||
var length = RoundToPadding(uints);
|
var length = RoundToPadding(uints);
|
||||||
|
|
||||||
_bits.Resize(length, option);
|
_bits.Resize(length, option);
|
||||||
@@ -712,7 +713,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
/// <returns>The <see cref="Span{T}"/>.</returns>
|
/// <returns>The <see cref="Span{T}"/>.</returns>
|
||||||
public readonly Span<uint> AsSpan()
|
public readonly Span<uint> AsSpan()
|
||||||
{
|
{
|
||||||
var max = _highestBit / (_BIT_SIZE + 1) + 1;
|
var max = _highestBit / (BIT_SIZE + 1) + 1;
|
||||||
return _bits.AsSpan()[..max];
|
return _bits.AsSpan()[..max];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,7 +825,7 @@ public unsafe struct UnsafeBitSet : IDisposable, IEquatable<UnsafeBitSet>
|
|||||||
/// represents a non resizable collection of bits.
|
/// represents a non resizable collection of bits.
|
||||||
/// Used to set, check and clear bits on a allocated <see cref="UnsafeBitSet"/> or on the stack.
|
/// Used to set, check and clear bits on a allocated <see cref="UnsafeBitSet"/> or on the stack.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
public readonly ref struct SpanBitSet : IUnsafeBitSet, IEquatable<SpanBitSet>
|
||||||
{
|
{
|
||||||
public ref struct Iterator
|
public ref struct Iterator
|
||||||
{
|
{
|
||||||
@@ -845,15 +846,17 @@ public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int _BIT_SIZE = sizeof(uint) * 8 - 1; // 31
|
private const int BIT_SIZE = sizeof(uint) * 8 - 1; // 31
|
||||||
// NOTE: Is a byte not 8 bits?
|
// NOTE: Is a byte not 8 bits?
|
||||||
private const int _BYTE_SIZE = 5; // log_2(BitSize + 1)
|
private const int BYTE_SIZE = 5; // log_2(BitSize + 1)
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bits from the bitset.
|
/// The bits from the bitset.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly Span<uint> _bits;
|
private readonly Span<uint> _bits;
|
||||||
|
|
||||||
|
public int Count => _bits.Length << BYTE_SIZE;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="UnsafeBitSet" /> class.
|
/// Initializes a new instance of the <see cref="UnsafeBitSet" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -874,13 +877,13 @@ public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
|||||||
/// <returns>True if it is, otherwise false</returns>
|
/// <returns>True if it is, otherwise false</returns>
|
||||||
public bool IsSet(int index)
|
public bool IsSet(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _BYTE_SIZE;
|
var b = index >> BYTE_SIZE;
|
||||||
if (b >= _bits.Length)
|
if (b >= _bits.Length)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (_bits[b] & 1 << (index & _BIT_SIZE)) != 0;
|
return (_bits[b] & 1 << (index & BIT_SIZE)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -890,13 +893,13 @@ public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
|||||||
/// <param name="index">The index.</param>
|
/// <param name="index">The index.</param>
|
||||||
public void SetBit(int index)
|
public void SetBit(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _BYTE_SIZE;
|
var b = index >> BYTE_SIZE;
|
||||||
if (b >= _bits.Length)
|
if (b >= _bits.Length)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_bits[b] |= 1u << (index & _BIT_SIZE);
|
_bits[b] |= 1u << (index & BIT_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -905,13 +908,13 @@ public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
|||||||
/// <param name="index">The index.</param>
|
/// <param name="index">The index.</param>
|
||||||
public void ClearBit(int index)
|
public void ClearBit(int index)
|
||||||
{
|
{
|
||||||
var b = index >> _BYTE_SIZE;
|
var b = index >> BYTE_SIZE;
|
||||||
if (b >= _bits.Length)
|
if (b >= _bits.Length)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_bits[b] &= ~(1u << (index & _BIT_SIZE));
|
_bits[b] &= ~(1u << (index & BIT_SIZE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -936,21 +939,21 @@ public readonly ref struct SpanBitSet : IEquatable<SpanBitSet>
|
|||||||
|
|
||||||
public int NextSetBit(int startIndex)
|
public int NextSetBit(int startIndex)
|
||||||
{
|
{
|
||||||
var wordIndex = startIndex >> _BIT_SIZE;
|
var wordIndex = startIndex >> BIT_SIZE;
|
||||||
if (wordIndex >= _bits.Length)
|
if (wordIndex >= _bits.Length)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask off bits below startIndex in the first word:
|
// Mask off bits below startIndex in the first word:
|
||||||
var word = _bits[wordIndex] & ~0u << (startIndex & UnsafeBitSet._MASK);
|
var word = _bits[wordIndex] & ~0u << (startIndex & UnsafeBitSet.MASK);
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (word != 0)
|
if (word != 0)
|
||||||
{
|
{
|
||||||
// get the least-significant set bit
|
// get the least-significant set bit
|
||||||
var bit = BitOperations.TrailingZeroCount(word);
|
var bit = BitOperations.TrailingZeroCount(word);
|
||||||
return (wordIndex << _BIT_SIZE) + bit;
|
return (wordIndex << BIT_SIZE) + bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
wordIndex++;
|
wordIndex++;
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ internal unsafe struct GGXMipGenerationJobSPMD : IJobSPMD<float, int>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
|
internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallel
|
||||||
where TFloat : unmanaged, ISPMDLane<TFloat, float>
|
where TFloat : unmanaged, ISPMDLane<TFloat, float>
|
||||||
where TInt : unmanaged, ISPMDLane<TInt, int>
|
where TInt : unmanaged, ISPMDLane<TInt, int>
|
||||||
{
|
{
|
||||||
@@ -248,22 +248,13 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
|
|||||||
return MathV.GatherVector3<TFloat, float>(img, idx.GetUnsafePtr(), 4);
|
return MathV.GatherVector3<TFloat, float>(img, idx.GetUnsafePtr(), 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
|
||||||
public void Execute(int loopIndex, ref readonly JobExecutionContext ctx)
|
private readonly void ProcessPixel(int local_i, MipLevel* pLevel)
|
||||||
{
|
{
|
||||||
var m = 0;
|
|
||||||
while (m < numMipLevels - 1 && loopIndex >= pMipLevels[m + 1].offset)
|
|
||||||
{
|
|
||||||
m++;
|
|
||||||
}
|
|
||||||
|
|
||||||
var pLevel = &pMipLevels[m];
|
|
||||||
|
|
||||||
var w = (int)pLevel->width;
|
var w = (int)pLevel->width;
|
||||||
var h = (int)pLevel->height;
|
var h = (int)pLevel->height;
|
||||||
var pData = pLevel->data;
|
var pData = pLevel->data;
|
||||||
|
|
||||||
var local_i = loopIndex - pLevel->offset;
|
|
||||||
var x = local_i % w;
|
var x = local_i % w;
|
||||||
var y = local_i / w;
|
var y = local_i / w;
|
||||||
var u = (float)x / (w - 1);
|
var u = (float)x / (w - 1);
|
||||||
@@ -358,6 +349,33 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
|
|||||||
pData[out_idx + 1] = prefilteredColor.y;
|
pData[out_idx + 1] = prefilteredColor.y;
|
||||||
pData[out_idx + 2] = prefilteredColor.z;
|
pData[out_idx + 2] = prefilteredColor.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveOptimization)]
|
||||||
|
public void Execute(int startIndex, int endIndex, ref readonly JobExecutionContext ctx)
|
||||||
|
{
|
||||||
|
var m = 0;
|
||||||
|
while (m < numMipLevels - 1 && startIndex >= pMipLevels[m + 1].offset)
|
||||||
|
{
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = startIndex;
|
||||||
|
|
||||||
|
while (i < endIndex)
|
||||||
|
{
|
||||||
|
var pLevel = &pMipLevels[m];
|
||||||
|
var next = m + 1 < numMipLevels ? pMipLevels[m + 1].offset : int.MaxValue;
|
||||||
|
var stop = Math.Min(endIndex, next);
|
||||||
|
|
||||||
|
for (; i < stop; i++)
|
||||||
|
{
|
||||||
|
var local_i = i - pLevel->offset;
|
||||||
|
ProcessPixel(local_i, pLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 1, invocationCount: 1, id: "QuickRun")]
|
[SimpleJob(RunStrategy.ColdStart, launchCount: 1, warmupCount: 0, iterationCount: 1, invocationCount: 1, id: "QuickRun")]
|
||||||
@@ -388,8 +406,8 @@ public unsafe class GGXMipGenerationBenchmark
|
|||||||
[GlobalSetup]
|
[GlobalSetup]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
//const string imagePath = "F:\\c\\SimpleRayTracer\\native\\assets\\hdri\\golden_gate_hills_1k.hdr";
|
const string imagePath = "F:\\c\\SimpleRayTracer\\native\\assets\\hdri\\golden_gate_hills_1k.hdr";
|
||||||
const string imagePath = "C:\\Users\\Misaki\\Downloads\\grasslands_sunset_4k.hdr";
|
//const string imagePath = "C:\\Users\\Misaki\\Downloads\\grasslands_sunset_4k.hdr";
|
||||||
using var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
|
using var stream = new FileStream(imagePath, FileMode.Open, FileAccess.Read);
|
||||||
_image = ImageResultFloat.FromStream(stream, ColorComponents.RGB);
|
_image = ImageResultFloat.FromStream(stream, ColorComponents.RGB);
|
||||||
|
|
||||||
@@ -517,7 +535,7 @@ public unsafe class GGXMipGenerationBenchmark
|
|||||||
radicalInverse_VdCLut = _radicalInverse_VdCLut
|
radicalInverse_VdCLut = _radicalInverse_VdCLut
|
||||||
};
|
};
|
||||||
|
|
||||||
handle = _jobScheduler.ScheduleParallelFor(in job, _totalPixel, 64);
|
handle = _jobScheduler.ScheduleParallel(in job, _totalPixel, 64);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -529,7 +547,7 @@ public unsafe class GGXMipGenerationBenchmark
|
|||||||
radicalInverse_VdCLut = _radicalInverse_VdCLut
|
radicalInverse_VdCLut = _radicalInverse_VdCLut
|
||||||
};
|
};
|
||||||
|
|
||||||
handle = _jobScheduler.ScheduleParallelFor(in job, _totalPixel, 64);
|
handle = _jobScheduler.ScheduleParallel(in job, _totalPixel, 64);
|
||||||
}
|
}
|
||||||
|
|
||||||
_jobScheduler.Wait(handle);
|
_jobScheduler.Wait(handle);
|
||||||
|
|||||||
Reference in New Issue
Block a user