using System; using System.Runtime.InteropServices; using Unity.Burst; using Unity.Collections; using Unity.Jobs; using Unity.Mathematics; namespace UnityEngine.Rendering.Universal { [StructLayout(LayoutKind.Sequential)] struct ZBin { public ushort minIndex; public ushort maxIndex; } [BurstCompile] unsafe struct ZBinningJob : IJobFor { // Do not use this for the innerloopBatchCount (use 1 for that). Use for dividing the arrayLength when scheduling. public const int batchCount = 64; [NativeDisableParallelForRestriction] public NativeArray bins; [ReadOnly] public NativeArray minMaxZs; public int binOffset; public float zFactor; public void Execute(int index) { var binsStart = batchCount * index; var binsEnd = math.min(binsStart + batchCount, bins.Length) - 1; for (var i = binsStart; i <= binsEnd; i++) { bins[i] = new ZBin { minIndex = ushort.MaxValue, maxIndex = ushort.MaxValue }; } for (var lightIndex = 0; lightIndex < minMaxZs.Length; lightIndex++) { var ushortLightIndex = (ushort)lightIndex; var minMax = minMaxZs[lightIndex]; var minBin = math.max((int)(math.sqrt(minMax.minZ) * zFactor) - binOffset, binsStart); var maxBin = math.min((int)(math.sqrt(minMax.maxZ) * zFactor) - binOffset, binsEnd); for (var binIndex = minBin; binIndex <= maxBin; binIndex++) { var bin = bins[binIndex]; bin.minIndex = Math.Min(bin.minIndex, ushortLightIndex); // This will always be the largest light index this bin has seen due to light iteration order. bin.maxIndex = ushortLightIndex; bins[binIndex] = bin; } } } } }