Skip to content

Commit 563e251

Browse files
Internal/master
Internal/master
2 parents f4f4006 + a596ef0 commit 563e251

File tree

510 files changed

+346238
-8811
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

510 files changed

+346238
-8811
lines changed

Packages/com.unity.render-pipelines.core/Editor/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,6 @@
44
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor.Tests")]
55
[assembly: InternalsVisibleTo("Unity.RenderPipelines.HighDefinition.Editor.Tests")]
66
[assembly: InternalsVisibleTo("Unity.RenderPipelines.Universal.Editor.Tests")]
7+
[assembly: InternalsVisibleTo("Unity.Testing.VisualEffectGraph.EditorTests")]
78
[assembly: InternalsVisibleTo("Assembly-CSharp-Editor-testable")]
89

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.LightTransport.cs

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,27 +1005,36 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA
10051005

10061006
if (!failed)
10071007
{
1008-
for (int c = 0; c < bakingCells.Length; c++)
1008+
// Validate baking cells size before any global state modifications
1009+
var chunkSizeInProbes = ProbeBrickPool.GetChunkSizeInProbeCount();
1010+
var hasVirtualOffsets = m_BakingSet.settings.virtualOffsetSettings.useVirtualOffset;
1011+
var hasRenderingLayers = m_BakingSet.useRenderingLayers;
1012+
1013+
if (ValidateBakingCellsSize(bakingCells, chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers))
10091014
{
1010-
ref var cell = ref bakingCells[c];
1011-
ComputeValidityMasks(cell);
1012-
}
1013-
1014-
// Write result to disk
1015-
WriteBakingCells(bakingCells);
1015+
for (int c = 0; c < bakingCells.Length; c++)
1016+
{
1017+
ref var cell = ref bakingCells[c];
1018+
ComputeValidityMasks(cell);
1019+
}
10161020

1017-
// Reload everything
1018-
AssetDatabase.SaveAssets();
1019-
AssetDatabase.Refresh();
1021+
// Attempt to write the result to disk
1022+
if (WriteBakingCells(bakingCells))
1023+
{
1024+
// Reload everything
1025+
AssetDatabase.SaveAssets();
1026+
AssetDatabase.Refresh();
10201027

1021-
if (m_BakingSet.hasDilation)
1022-
{
1023-
// Force reloading of data
1024-
foreach (var data in prv.perSceneDataList)
1025-
data.Initialize();
1028+
if (m_BakingSet.hasDilation)
1029+
{
1030+
// Force reloading of data
1031+
foreach (var data in prv.perSceneDataList)
1032+
data.Initialize();
10261033

1027-
InitDilationShaders();
1028-
PerformDilation();
1034+
InitDilationShaders();
1035+
PerformDilation();
1036+
}
1037+
}
10291038
}
10301039
}
10311040
}
@@ -1045,6 +1054,7 @@ internal static void BakeAdjustmentVolume(ProbeVolumeBakingSet bakingSet, ProbeA
10451054
bakingSet.settings.virtualOffsetSettings.useVirtualOffset = savedVirtualOffset;
10461055
bakingSet.useRenderingLayers = savedRenderingLayers;
10471056

1057+
m_BakingBatch?.Dispose();
10481058
m_BakingBatch = null;
10491059
m_BakingSet = null;
10501060
}

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Placement.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
using Unity.Collections;
44
using UnityEngine.SceneManagement;
55
using UnityEditor;
6-
6+
using System.Runtime.InteropServices;
77
using Brick = UnityEngine.Rendering.ProbeBrickIndex.Brick;
88

99
namespace UnityEngine.Rendering
@@ -191,7 +191,8 @@ static NativeList<Vector3> ApplySubdivisionResults(ProbeSubdivisionResult result
191191
int positionStart = positions.Length;
192192

193193
ConvertBricksToPositions(bricks, out var probePositions, out var brickSubdivLevels);
194-
DeduplicateProbePositions(in probePositions, in brickSubdivLevels, m_BakingBatch, positions, out var probeIndices);
194+
if (!DeduplicateProbePositions(in probePositions, in brickSubdivLevels, m_BakingBatch, positions, out var probeIndices))
195+
return new NativeList<Vector3>(Allocator.Persistent);
195196

196197
BakingCell cell = new BakingCell()
197198
{
@@ -210,9 +211,22 @@ static NativeList<Vector3> ApplySubdivisionResults(ProbeSubdivisionResult result
210211
return positions;
211212
}
212213

213-
private static void DeduplicateProbePositions(in Vector3[] probePositions, in int[] brickSubdivLevel, BakingBatch batch,
214+
// We know that the current limitation on native containers is this. When an integer overflow bug (https://jira.unity3d.com/browse/UUM-113721) has been fixed, we can raise the limit
215+
// This and related work is tracked by https://jira.unity3d.com/browse/GFXLIGHT-1738
216+
static readonly long k_MaxNumberOfPositions = 67180350;
217+
218+
static bool DeduplicateProbePositions(in Vector3[] probePositions, in int[] brickSubdivLevel, BakingBatch batch,
214219
NativeList<Vector3> uniquePositions, out int[] indices)
215220
{
221+
long numberOfPositions = (long)probePositions.Length + batch.positionToIndex.Count;
222+
if (numberOfPositions > k_MaxNumberOfPositions)
223+
{
224+
Debug.LogError($"The number of Adaptive Probe Volume (APV) probes Unity generated exceeds the current system limit of {k_MaxNumberOfPositions} probes per Baking Set. Reduce density either by adjusting the general Probe Spacing in the Lighting window, or by modifying the Adaptive Probe Volumes in the scene to limit where the denser subdivision levels are used.");
225+
indices = null;
226+
227+
return false;
228+
}
229+
216230
indices = new int[probePositions.Length];
217231
int uniqueIndex = batch.positionToIndex.Count;
218232

@@ -238,6 +252,8 @@ private static void DeduplicateProbePositions(in Vector3[] probePositions, in in
238252
uniqueIndex++;
239253
}
240254
}
255+
256+
return true;
241257
}
242258

243259
static ProbeSubdivisionResult GetBricksFromLoaded(List<ProbeVolumePerSceneData> dataList)

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,63 @@ static void ExtractBakingCells()
726726

727727
static long AlignRemainder16(long count) => count % 16L;
728728

729+
/// <summary>
730+
/// Calculates support data chunk size based on provided configuration.
731+
/// </summary>
732+
/// <param name="chunkSizeInProbes">Number of probes per chunk</param>
733+
/// <param name="hasVirtualOffsets">Whether virtual offsets are enabled</param>
734+
/// <param name="hasRenderingLayers">Whether rendering layers are enabled</param>
735+
/// <returns>The size in bytes of a single support data chunk</returns>
736+
static int CalculateSupportDataChunkSize(int chunkSizeInProbes, bool hasVirtualOffsets, bool hasRenderingLayers)
737+
{
738+
int supportPositionChunkSize = UnsafeUtility.SizeOf<Vector3>() * chunkSizeInProbes;
739+
int supportValidityChunkSize = UnsafeUtility.SizeOf<float>() * chunkSizeInProbes;
740+
int supportTouchupChunkSize = UnsafeUtility.SizeOf<float>() * chunkSizeInProbes;
741+
int supportLayerMaskChunkSize = hasRenderingLayers ? UnsafeUtility.SizeOf<byte>() * chunkSizeInProbes : 0;
742+
int supportOffsetsChunkSize = hasVirtualOffsets ? UnsafeUtility.SizeOf<Vector3>() * chunkSizeInProbes : 0;
743+
744+
return supportPositionChunkSize + supportValidityChunkSize +
745+
supportOffsetsChunkSize + supportLayerMaskChunkSize + supportTouchupChunkSize;
746+
}
747+
748+
/// <summary>
749+
/// Validates that the baking cells can be written without exceeding system limits.
750+
/// This method performs size calculations without accessing any global state.
751+
/// </summary>
752+
/// <param name="bakingCells">Array of baking cells to validate</param>
753+
/// <param name="chunkSizeInProbes">Number of probes per chunk</param>
754+
/// <param name="hasVirtualOffsets">Whether virtual offsets are enabled</param>
755+
/// <param name="hasRenderingLayers">Whether rendering layers are enabled</param>
756+
/// <returns>True if cells can be written safely, false if they exceed limits</returns>
757+
static bool ValidateBakingCellsSize(BakingCell[] bakingCells, int chunkSizeInProbes, bool hasVirtualOffsets, bool hasRenderingLayers)
758+
{
759+
if (bakingCells == null || bakingCells.Length == 0)
760+
return true;
761+
762+
int supportDataChunkSize = CalculateSupportDataChunkSize(chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers);
763+
764+
// Calculate total chunks count - need to call AnalyzeBrickForIndirectionEntries to get shChunkCount
765+
// Create a copy to avoid modifying the original cells during validation
766+
var tempCells = new BakingCell[bakingCells.Length];
767+
int totalChunksCount = 0;
768+
for (var i = 0; i < bakingCells.Length; ++i)
769+
{
770+
tempCells[i] = bakingCells[i]; // Shallow copy is sufficient for this validation
771+
AnalyzeBrickForIndirectionEntries(ref tempCells[i]);
772+
totalChunksCount += tempCells[i].shChunkCount;
773+
}
774+
775+
// Perform the critical size check
776+
long supportDataTotalSize = (long)totalChunksCount * supportDataChunkSize;
777+
if (supportDataTotalSize > int.MaxValue)
778+
{
779+
Debug.LogError($"The size of the Adaptive Probe Volume (APV) baking set chunks exceed the current system limit of {int.MaxValue}, unable to save the baked cell assets. Reduce density either by adjusting the general Probe Spacing in the Lighting window, or by modifying the Adaptive Probe Volumes in the scene to limit where the denser subdivision levels are used.");
780+
return false;
781+
}
782+
783+
return true;
784+
}
785+
729786
static void WriteNativeArray<T>(System.IO.FileStream fs, NativeArray<T> array) where T : struct
730787
{
731788
unsafe
@@ -736,7 +793,7 @@ static void WriteNativeArray<T>(System.IO.FileStream fs, NativeArray<T> array) w
736793
}
737794

738795
/// <summary>
739-
/// This method converts a list of baking cells into 5 separate assets:
796+
/// This method attempts to convert a list of baking cells into 5 separate assets:
740797
/// 2 assets per baking state:
741798
/// CellData: a binary flat file containing L0L1 probes data
742799
/// CellOptionalData: a binary flat file containing L2 probe data (when present)
@@ -745,7 +802,7 @@ static void WriteNativeArray<T>(System.IO.FileStream fs, NativeArray<T> array) w
745802
/// CellSharedData: a binary flat file containing bricks data
746803
/// CellSupportData: a binary flat file containing debug data (stripped from player builds if building without debug shaders)
747804
/// </summary>
748-
unsafe static void WriteBakingCells(BakingCell[] bakingCells)
805+
static unsafe bool WriteBakingCells(BakingCell[] bakingCells)
749806
{
750807
m_BakingSet.GetBlobFileNames(m_BakingSet.lightingScenario, out var cellDataFilename, out var cellBricksDataFilename, out var cellOptionalDataFilename, out var cellProbeOcclusionDataFilename, out var cellSharedDataFilename, out var cellSupportDataFilename);
751808

@@ -846,16 +903,16 @@ unsafe static void WriteBakingCells(BakingCell[] bakingCells)
846903
// Brick data
847904
using var bricks = new NativeArray<Brick>(m_TotalCellCounts.bricksCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
848905

849-
// CellSupportData
850-
m_BakingSet.supportPositionChunkSize = sizeof(Vector3) * chunkSizeInProbes;
851-
m_BakingSet.supportValidityChunkSize = sizeof(float) * chunkSizeInProbes;
852-
m_BakingSet.supportOffsetsChunkSize = hasVirtualOffsets ? sizeof(Vector3) * chunkSizeInProbes : 0;
853-
m_BakingSet.supportTouchupChunkSize = sizeof(float) * chunkSizeInProbes;
854-
m_BakingSet.supportLayerMaskChunkSize = hasRenderingLayers ? sizeof(byte) * chunkSizeInProbes : 0;
906+
// CellSupportData - use pure helper function for calculation
907+
m_BakingSet.supportPositionChunkSize = UnsafeUtility.SizeOf<Vector3>() * chunkSizeInProbes;
908+
m_BakingSet.supportValidityChunkSize = UnsafeUtility.SizeOf<float>() * chunkSizeInProbes;
909+
m_BakingSet.supportOffsetsChunkSize = hasVirtualOffsets ? UnsafeUtility.SizeOf<Vector3>() * chunkSizeInProbes : 0;
910+
m_BakingSet.supportTouchupChunkSize = UnsafeUtility.SizeOf<float>() * chunkSizeInProbes;
911+
m_BakingSet.supportLayerMaskChunkSize = hasRenderingLayers ? UnsafeUtility.SizeOf<byte>() * chunkSizeInProbes : 0;
855912

856-
m_BakingSet.supportDataChunkSize = m_BakingSet.supportPositionChunkSize + m_BakingSet.supportValidityChunkSize + m_BakingSet.supportOffsetsChunkSize + m_BakingSet.supportLayerMaskChunkSize + m_BakingSet.supportTouchupChunkSize;
857-
var supportDataTotalSize = m_TotalCellCounts.chunksCount * m_BakingSet.supportDataChunkSize;
858-
using var supportData = new NativeArray<byte>(supportDataTotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
913+
m_BakingSet.supportDataChunkSize = CalculateSupportDataChunkSize(chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers);
914+
long supportDataTotalSize = (long)m_TotalCellCounts.chunksCount * m_BakingSet.supportDataChunkSize;
915+
using var supportData = new NativeArray<byte>((int)supportDataTotalSize, Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
859916

860917
var sceneStateHash = m_BakingSet.GetBakingHashCode();
861918
var startCounts = new CellCounts();
@@ -1093,6 +1150,8 @@ unsafe static void WriteBakingCells(BakingCell[] bakingCells)
10931150
m_BakingSet.cellSupportDataAsset = new ProbeVolumeStreamableAsset(kAPVStreamingAssetsPath, cellSupportDescs, m_BakingSet.supportDataChunkSize, bakingSetGUID, AssetDatabase.AssetPathToGUID(cellSupportDataFilename));
10941151

10951152
EditorUtility.SetDirty(m_BakingSet);
1153+
1154+
return true;
10961155
}
10971156

10981157
unsafe static void WriteDilatedCells(List<Cell> cells)

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.VirtualOffset.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,19 @@ static internal void RecomputeVOForDebugOnly()
342342
// Make sure unloading happens.
343343
prv.PerformPendingOperations();
344344

345-
// Write back the assets.
346-
WriteBakingCells(m_BakingBatch.cells.ToArray());
345+
// Validate baking cells size before writing
346+
var bakingCellsArray = m_BakingBatch.cells.ToArray();
347+
var chunkSizeInProbes = ProbeBrickPool.GetChunkSizeInProbeCount();
348+
var hasVirtualOffsets = m_BakingSet.settings.virtualOffsetSettings.useVirtualOffset;
349+
var hasRenderingLayers = m_BakingSet.useRenderingLayers;
350+
351+
if (ValidateBakingCellsSize(bakingCellsArray, chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers))
352+
{
353+
// Write back the assets.
354+
WriteBakingCells(bakingCellsArray);
355+
}
356+
357+
m_BakingBatch?.Dispose();
347358
m_BakingBatch = null;
348359

349360
foreach (var data in prv.perSceneDataList)

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.cs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -268,15 +268,15 @@ internal int GetBakingHashCode()
268268
}
269269
}
270270

271-
class BakingBatch
271+
class BakingBatch : IDisposable
272272
{
273273
public Dictionary<int, HashSet<string>> cellIndex2SceneReferences = new ();
274274
public List<BakingCell> cells = new ();
275275
// Used to retrieve probe data from it's position in order to fix seams
276-
public Dictionary<int, int> positionToIndex = new ();
276+
public NativeHashMap<int, int> positionToIndex;
277277
// Allow to get a mapping to subdiv level with the unique positions. It stores the minimum subdiv level found for a given position.
278278
// Can be probably done cleaner.
279-
public Dictionary<int, int> uniqueBrickSubdiv = new ();
279+
public NativeHashMap<int, int> uniqueBrickSubdiv;
280280
// Mapping for explicit invalidation, whether it comes from the auto finding of occluders or from the touch up volumes
281281
// TODO: This is not used yet. Will soon.
282282
public Dictionary<Vector3, bool> invalidatedPositions = new ();
@@ -306,6 +306,19 @@ public BakingBatch(Vector3Int cellCount, ProbeReferenceVolume refVolume)
306306
maxBrickCount = cellCount * ProbeReferenceVolume.CellSize(refVolume.GetMaxSubdivision());
307307
inverseScale = ProbeBrickPool.kBrickCellCount / refVolume.MinBrickSize();
308308
offset = refVolume.ProbeOffset();
309+
310+
// Initialize NativeHashMaps with reasonable initial capacity
311+
// Using a larger capacity to reduce allocations during baking
312+
positionToIndex = new NativeHashMap<int, int>(100000, Allocator.Persistent);
313+
uniqueBrickSubdiv = new NativeHashMap<int, int>(100000, Allocator.Persistent);
314+
}
315+
316+
public void Dispose()
317+
{
318+
if (positionToIndex.IsCreated)
319+
positionToIndex.Dispose();
320+
if (uniqueBrickSubdiv.IsCreated)
321+
uniqueBrickSubdiv.Dispose();
309322
}
310323

311324
public int GetProbePositionHash(Vector3 position)
@@ -1202,6 +1215,7 @@ static void OnBakeCancelled()
12021215
static void CleanBakeData()
12031216
{
12041217
s_BakeData.Dispose();
1218+
m_BakingBatch?.Dispose();
12051219
m_BakingBatch = null;
12061220
s_AdjustmentVolumes = null;
12071221

@@ -1478,6 +1492,15 @@ static void ApplyPostBakeOperations()
14781492
// Use the globalBounds we just computed, as the one in probeRefVolume doesn't include scenes that have never been baked
14791493
probeRefVolume.globalBounds = globalBounds;
14801494

1495+
// Validate baking cells size before any state modifications
1496+
var bakingCellsArray = m_BakedCells.Values.ToArray();
1497+
var chunkSizeInProbes = ProbeBrickPool.GetChunkSizeInProbeCount();
1498+
var hasVirtualOffsets = m_BakingSet.settings.virtualOffsetSettings.useVirtualOffset;
1499+
var hasRenderingLayers = m_BakingSet.useRenderingLayers;
1500+
1501+
if (!ValidateBakingCellsSize(bakingCellsArray, chunkSizeInProbes, hasVirtualOffsets, hasRenderingLayers))
1502+
return; // Early exit if validation fails
1503+
14811504
PrepareCellsForWriting(isBakingSceneSubset);
14821505

14831506
m_BakingSet.chunkSizeInBricks = ProbeBrickPool.GetChunkSizeInBrickCount();
@@ -1488,9 +1511,13 @@ static void ApplyPostBakeOperations()
14881511

14891512
m_BakingSet.scenarios.TryAdd(m_BakingSet.lightingScenario, new ProbeVolumeBakingSet.PerScenarioDataInfo());
14901513

1491-
// Convert baking cells to runtime cells
1514+
// Attempt to convert baking cells to runtime cells
1515+
bool succeededWritingBakingCells;
14921516
using (new BakingCompleteProfiling(BakingCompleteProfiling.Stages.WriteBakedData))
1493-
WriteBakingCells(m_BakedCells.Values.ToArray());
1517+
succeededWritingBakingCells = WriteBakingCells(m_BakedCells.Values.ToArray());
1518+
1519+
if (!succeededWritingBakingCells)
1520+
return;
14941521

14951522
// Reset internal structures depending on current bake.
14961523
Debug.Assert(probeRefVolume.EnsureCurrentBakingSet(m_BakingSet));
@@ -1534,6 +1561,7 @@ static void ApplyPostBakeOperations()
15341561
}
15351562

15361563
// Mark stuff as up to date
1564+
m_BakingBatch?.Dispose();
15371565
m_BakingBatch = null;
15381566
foreach (var probeVolume in GetProbeVolumeList())
15391567
probeVolume.OnBakeCompleted();

Packages/com.unity.render-pipelines.core/Editor/Properties/PropertiesPreferencesProvider.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ class Styles
1919

2020
public void PreferenceGUI()
2121
{
22+
EditorGUI.indentLevel++;
2223
AdvancedProperties.enabled = EditorGUILayout.IntPopup(Styles.additionalPropertiesLabel,
2324
AdvancedProperties.enabled ? 1 : 0, Styles.additionalPropertiesNames,
2425
Styles.additionalPropertiesValues) == 1;
26+
EditorGUI.indentLevel--;
2527
}
2628
}
2729
}

0 commit comments

Comments
 (0)