Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

168 changes: 103 additions & 65 deletions com.unity.render-pipelines.core/Runtime/BatchRenderer/RenderBRG.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,13 +137,6 @@ internal struct BRGInstanceBufferOffsets
public int probeOffsetOcclusion;
}

struct DeferredMaterialInstance
{
public int instanceIndex;
public int meshHashCode;
public GeometryPoolHandle geoPoolHandle;
}

unsafe class SceneBRG
{
private BatchRendererGroup m_BatchRendererGroup;
Expand All @@ -162,12 +155,12 @@ unsafe class SceneBRG
private NativeArray<int> m_instanceIndices;
private NativeArray<int> m_drawIndices;
private BRGInstanceBufferOffsets m_instanceBufferOffsets;
private NativeList<DeferredMaterialInstance> m_deferredMaterialInstances;

private LightMaps m_Lightmaps;

private BRGTransformUpdater m_BRGTransformUpdater = new BRGTransformUpdater();
private GeometryPool m_GlobalGeoPool = null;
private DeferredMaterialBRG m_DeferredMaterialBRG = null;
GeometryPoolBatchHandle m_DeferredMaterialBatch = GeometryPoolBatchHandle.Invalid;

private List<MeshRenderer> m_AddedRenderers;

Expand Down Expand Up @@ -750,7 +743,7 @@ public JobHandle OnPerformCulling(BatchRendererGroup rendererGroup, BatchCulling
return jobHandleOutput;
}

private void ProcessUsedMeshAndMaterialDataFromGameObjects(
private bool ProcessUsedMeshAndMaterialDataFromGameObjects(
RenderPipelineAsset activePipelineAsset,
RenderBRGGetMaterialRenderInfoCallback onGetMaterialInfoCb,
int instanceIndex,
Expand Down Expand Up @@ -788,6 +781,9 @@ private void ProcessUsedMeshAndMaterialDataFromGameObjects(
material = matToUse
});

if (!visMaterialInfo.supportsBRGRendering)
return false;

if (visMaterialInfo.supportsVisibility && visMaterialInfo.materialOverride != null)
{
Assert.IsTrue(
Expand All @@ -806,32 +802,41 @@ private void ProcessUsedMeshAndMaterialDataFromGameObjects(

//Special case, if the renderer qualifies for deferred materials, go for it!
//TODO: for now we just handle 1 case, if the entire renderer can be deferred material.
if (overrideMaterial != null && overrideCounts == outMaterials.Count && m_GlobalGeoPool != null)
if (overrideMaterial != null && overrideCounts == outMaterials.Count && m_DeferredMaterialBatch.valid)
{
m_GlobalGeoPool.Register(outMesh, out GeometryPoolHandle geoPoolHandle);
if (!geoPoolHandle.valid)
return;
GeometryPoolEntryDesc geoPoolEntryDesc = new GeometryPoolEntryDesc()
{
mesh = outMesh,
submeshData = outSubmeshIndices.Count != 0u ? new GeometryPoolSubmeshData[outSubmeshIndices.Count] : null
};

if (!m_deferredMaterialInstances.IsCreated)
m_deferredMaterialInstances = new NativeList<DeferredMaterialInstance>(1024, Allocator.Persistent);
for (int i = 0; i < outSubmeshIndices.Count; ++i)
{
geoPoolEntryDesc.submeshData[i] = new GeometryPoolSubmeshData()
{
submeshIndex = outSubmeshIndices[i],
material = outMaterials[i]
};
}

m_deferredMaterialInstances.Add(new DeferredMaterialInstance()
GeometryPoolHandle geoHandle = GeometryPoolHandle.Invalid;
if (!m_DeferredMaterialBRG.RegisterInstance(m_DeferredMaterialBatch, instanceIndex, geoPoolEntryDesc, out geoHandle))
{
instanceIndex = instanceIndex,
meshHashCode = outMesh.GetHashCode(),
geoPoolHandle = geoPoolHandle
});
Debug.LogError("Could not register instance into deferred material batch: ." + renderer);
return true;
}

deferredMaterialBuffer[deferredMaterialBufferOffset + instanceIndex] = new Vector4((float)geoPoolHandle.index, 0.0f, 0.0f, 0.0f);
deferredMaterialBuffer[deferredMaterialBufferOffset + instanceIndex] = new Vector4((float)geoHandle.index, m_DeferredMaterialBatch.index, 0.0f, 0.0f);

//We succeeded! lets override the mesh / submesh index and material.
outSubmeshIndices.Clear();
outMaterials.Clear();
outMaterials.Add(overrideMaterial);
outSubmeshIndices.Add(geoPoolHandle.index);
outMesh = m_GlobalGeoPool.globalMesh;

outSubmeshIndices.Add(geoHandle.index);
outMesh = m_DeferredMaterialBRG.globalGeoMesh;
}

return true;
}

private void SanityCheckDrawInstanceCounts()
Expand All @@ -856,7 +861,7 @@ private void SanityCheckDrawInstanceCounts()
}

// Start is called before the first frame update
public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
public void Initialize(List<MeshRenderer> renderers, DeferredMaterialBRG deferredMaterialBRG)
{
m_BatchRendererGroup = new BatchRendererGroup(this.OnPerformCulling, IntPtr.Zero);
m_BRGTransformUpdater.Initialize();
Expand All @@ -872,7 +877,7 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
m_drawBatches = new NativeList<DrawBatch>(Allocator.Persistent);
m_drawRanges = new NativeList<DrawRange>(Allocator.Persistent);
m_AddedRenderers = new List<MeshRenderer>(renderersLength);
m_GlobalGeoPool = geometryPool;
m_DeferredMaterialBRG = deferredMaterialBRG;

// Fill the GPU-persistent scene data ComputeBuffer
int bigDataBufferVector4Count =
Expand Down Expand Up @@ -937,6 +942,11 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
LightProbesQuery lpq = new LightProbesQuery(Allocator.Temp);
bool useFirstMeshForAll = false; // Hack to help benchmarking different bottlenecks. TODO: Remove!
MeshFilter firstMesh = null;
if (m_DeferredMaterialBRG != null)
{
if (!m_DeferredMaterialBRG.CreateBatch(renderers.Count, out m_DeferredMaterialBatch))
Debug.LogError("Could not allocate batch for this scene, not enough gpu memory allocated.");
}

RenderBRGGetMaterialRenderInfoCallback onGetMaterialInfoCb = RenderBRG.GetActiveMaterialRenderInfoCallback(out RenderPipelineAsset activePipeline);

Expand All @@ -956,6 +966,15 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
firstMesh = meshFilter;
}

Mesh usedMesh = null;
var usedSubmeshIndices = new List<int>();
var usedMaterials = new List<Material>();
if (!ProcessUsedMeshAndMaterialDataFromGameObjects(
activePipeline, onGetMaterialInfoCb, i, renderer, meshFilter, rendererMaterialInfos,
deferredMaterialDataOffset, vectorBuffer,
ref usedMesh, usedSubmeshIndices, usedMaterials))
continue;

m_AddedRenderers.Add(renderer);

// Disable the existing Unity MeshRenderer to avoid double rendering!
Expand Down Expand Up @@ -1001,14 +1020,6 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)

m_BRGTransformUpdater.RegisterTransformObject(i, rendererTransform, meshFilter.sharedMesh, renderer.lightProbeUsage == LightProbeUsage.BlendProbes);

Mesh usedMesh = null;
var usedSubmeshIndices = new List<int>();
var usedMaterials = new List<Material>();
ProcessUsedMeshAndMaterialDataFromGameObjects(
activePipeline, onGetMaterialInfoCb, i, renderer, meshFilter, rendererMaterialInfos,
deferredMaterialDataOffset, vectorBuffer,
ref usedMesh, usedSubmeshIndices, usedMaterials);

var mesh = m_BatchRendererGroup.RegisterMesh(usedMesh);

// Different renderer settings? -> new draw range
Expand Down Expand Up @@ -1082,9 +1093,6 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
}
}

if (m_GlobalGeoPool != null)
m_GlobalGeoPool.SendGpuCommands();

m_GPUPersistentInstanceData =
new GraphicsBuffer(GraphicsBuffer.Target.Raw, (int)bigDataBufferVector4Count * 16 / 4, 4);
m_GPUPersistentInstanceData.SetData(vectorBuffer);
Expand Down Expand Up @@ -1195,6 +1203,9 @@ public void Initialize(List<MeshRenderer> renderers, GeometryPool geometryPool)
// Register batch
m_batchID = m_BatchRendererGroup.AddBatch(batchMetadata, m_GPUPersistentInstanceData.bufferHandle);

if (m_DeferredMaterialBatch.valid)
m_DeferredMaterialBRG.SubmitBatch(m_DeferredMaterialBatch, batchMetadata, m_GPUPersistentInstanceData.bufferHandle);

m_initialized = true;
}

Expand Down Expand Up @@ -1235,21 +1246,18 @@ public void Destroy()
added.forceRenderingOff = false;
}

if (m_deferredMaterialInstances.IsCreated)
if (m_DeferredMaterialBatch.valid)
{
foreach (var deferredInstance in m_deferredMaterialInstances)
{
m_GlobalGeoPool.UnregisterByMeshHashCode(deferredInstance.meshHashCode);
}
m_GlobalGeoPool.SendGpuCommands();
m_deferredMaterialInstances.Dispose();
m_DeferredMaterialBRG.DestroyBatch(m_DeferredMaterialBatch);
m_DeferredMaterialBatch = GeometryPoolBatchHandle.Invalid;
}
}
}
}

public struct RenderBRGMaterialRenderInfo
{
public bool supportsBRGRendering;
public bool supportsVisibility;
public Material materialOverride;
}
Expand All @@ -1264,6 +1272,21 @@ public struct RenderBRGGetMaterialRenderInfoArgs

public delegate RenderBRGMaterialRenderInfo RenderBRGGetMaterialRenderInfoCallback(RenderBRGGetMaterialRenderInfoArgs arguments);

public struct RenderBRGBindingData
{
public GeometryPool globalGeometryPool;

public bool valid => globalGeometryPool != null;

public static RenderBRGBindingData NewDefault()
{
return new RenderBRGBindingData()
{
globalGeometryPool = null
};
}
}

public class RenderBRG : MonoBehaviour
{
private static Dictionary<Type, RenderBRGGetMaterialRenderInfoCallback> s_SrpMatInfoCallbacks = new();
Expand Down Expand Up @@ -1293,26 +1316,20 @@ internal static RenderBRGGetMaterialRenderInfoCallback GetActiveMaterialRenderIn
public bool EnableTransformUpdate = true;
private GeometryPool m_GlobalGeoPool;

public static GeometryPool FindGlobalGeometryPool()
{
RenderBRG[] brgers = Resources.FindObjectsOfTypeAll<RenderBRG>();
if (brgers == null)
return null;
private static uint s_DeferredMaterialBRGRef = 0;
private static DeferredMaterialBRG s_DeferredMaterialBRG;

foreach (var brg in brgers)
public static RenderBRGBindingData GetRenderBRGMaterialBindingData()
{
return new RenderBRGBindingData()
{
if (brg.m_GlobalGeoPool != null)
return brg.m_GlobalGeoPool;
}

return null;
globalGeometryPool = s_DeferredMaterialBRG == null ? null : s_DeferredMaterialBRG.geometryPool
};
}

private void OnEnable()
{
var globalGeoPool = FindGlobalGeometryPool();
if (EnableDeferredMaterials && globalGeoPool == null && m_GlobalGeoPool == null)
m_GlobalGeoPool = new GeometryPool(GeometryPoolDesc.NewDefault());
CreateDeferredMaterialBRG();

m_gpuCmdBuffer = new CommandBuffer();
SceneManager.sceneLoaded += OnSceneLoaded;
Expand Down Expand Up @@ -1356,6 +1373,31 @@ private void OnDisable()

foreach (var scene in toNull)
m_Scenes[scene] = null;

DisposeDeferredMaterialBRG();
}

private void CreateDeferredMaterialBRG()
{
if (!EnableDeferredMaterials)
return;
if (s_DeferredMaterialBRGRef == 0)
s_DeferredMaterialBRG = new DeferredMaterialBRG();
++s_DeferredMaterialBRGRef;
}

private void DisposeDeferredMaterialBRG()
{
if (s_DeferredMaterialBRG == null)
return;

--s_DeferredMaterialBRGRef;

if (s_DeferredMaterialBRGRef > 0)
return;

s_DeferredMaterialBRG.Dispose();
s_DeferredMaterialBRG = null;
}

private static void GetValidChildRenderers(GameObject root, List<MeshRenderer> toAppend)
Expand Down Expand Up @@ -1390,7 +1432,7 @@ private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
Debug.Log("Loading scene: " + scene.name);
#endif
SceneBRG brg = new SceneBRG();
brg.Initialize(renderers, RenderBRG.FindGlobalGeometryPool());
brg.Initialize(renderers, s_DeferredMaterialBRG);
m_Scenes[scene] = brg;
}

Expand Down Expand Up @@ -1440,11 +1482,7 @@ private void OnDestroy()

m_Scenes.Clear();

if (m_GlobalGeoPool != null)
{
m_GlobalGeoPool.Dispose();
m_GlobalGeoPool = null;
}
DisposeDeferredMaterialBRG();
}
}
}
Loading