123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- using System;
- using System.Collections.Generic;
- using Unity.Collections;
- using Unity.Jobs;
- using UnityEngine.Profiling;
- using Unity.Mathematics;
- using UnityEngine.Assertions;
- using UnityEngine.Rendering.RenderGraphModule;
-
- namespace UnityEngine.Rendering
- {
- internal partial class GPUResidentBatcher : IDisposable
- {
- private RenderersBatchersContext m_BatchersContext;
- private GPUDrivenProcessor m_GPUDrivenProcessor;
- private GPUDrivenRendererDataCallback m_UpdateRendererDataCallback;
-
- internal RenderersBatchersContext batchersContext { get => m_BatchersContext; }
- internal OcclusionCullingCommon occlusionCullingCommon { get => m_BatchersContext.occlusionCullingCommon; }
- internal InstanceCullingBatcher instanceCullingBatcher { get => m_InstanceCullingBatcher; }
-
- private InstanceCullingBatcher m_InstanceCullingBatcher = null;
-
- public GPUResidentBatcher(
- RenderersBatchersContext batcherContext,
- InstanceCullingBatcherDesc instanceCullerBatcherDesc,
- GPUDrivenProcessor gpuDrivenProcessor)
- {
- m_BatchersContext = batcherContext;
- m_GPUDrivenProcessor = gpuDrivenProcessor;
- m_UpdateRendererDataCallback = UpdateRendererData;
-
- m_InstanceCullingBatcher = new InstanceCullingBatcher(batcherContext, instanceCullerBatcherDesc, OnFinishedCulling);
- }
-
- public void Dispose()
- {
- m_GPUDrivenProcessor.ClearMaterialFilters();
- m_InstanceCullingBatcher.Dispose();
-
- if (m_ProcessedThisFrameTreeBits.IsCreated)
- m_ProcessedThisFrameTreeBits.Dispose();
- }
-
- public void OnBeginContextRendering()
- {
- if (m_ProcessedThisFrameTreeBits.IsCreated)
- m_ProcessedThisFrameTreeBits.Dispose();
- }
-
- public void OnEndContextRendering()
- {
- m_InstanceCullingBatcher?.OnEndContextRendering();
- }
-
- public void OnBeginCameraRendering(Camera camera)
- {
- m_InstanceCullingBatcher?.OnBeginCameraRendering(camera);
- }
-
- public void OnEndCameraRendering(Camera camera)
- {
- m_InstanceCullingBatcher?.OnEndCameraRendering(camera);
- }
-
- public void UpdateFrame()
- {
- m_InstanceCullingBatcher.UpdateFrame();
- m_BatchersContext.UpdateFrame();
- }
-
- public void DestroyMaterials(NativeArray<int> destroyedMaterials)
- {
- m_InstanceCullingBatcher.DestroyMaterials(destroyedMaterials);
- }
-
- public void DestroyInstances(NativeArray<InstanceHandle> instances)
- {
- m_InstanceCullingBatcher.DestroyInstances(instances);
- }
-
- public void DestroyMeshes(NativeArray<int> destroyedMeshes)
- {
- m_InstanceCullingBatcher.DestroyMeshes(destroyedMeshes);
- }
-
- internal void FreeRendererGroupInstances(NativeArray<int> rendererGroupIDs)
- {
- if (rendererGroupIDs.Length == 0)
- return;
-
- var instances = new NativeList<InstanceHandle>(rendererGroupIDs.Length, Allocator.TempJob);
- m_BatchersContext.ScheduleQueryRendererGroupInstancesJob(rendererGroupIDs, instances).Complete();
- DestroyInstances(instances.AsArray());
- instances.Dispose();
-
- m_BatchersContext.FreeRendererGroupInstances(rendererGroupIDs);
- }
-
- public void InstanceOcclusionTest(RenderGraph renderGraph, in OcclusionCullingSettings settings, ReadOnlySpan<SubviewOcclusionTest> subviewOcclusionTests)
- {
- if (!m_BatchersContext.hasBoundingSpheres)
- return;
-
- m_InstanceCullingBatcher.culler.InstanceOcclusionTest(renderGraph, settings, subviewOcclusionTests, m_BatchersContext);
- }
-
- public void UpdateInstanceOccluders(RenderGraph renderGraph, in OccluderParameters occluderParams, ReadOnlySpan<OccluderSubviewUpdate> occluderSubviewUpdates)
- {
- if (!m_BatchersContext.hasBoundingSpheres)
- return;
-
- m_BatchersContext.occlusionCullingCommon.UpdateInstanceOccluders(renderGraph, occluderParams, occluderSubviewUpdates);
- }
-
- public void UpdateRenderers(NativeArray<int> renderersID)
- {
- if (renderersID.Length == 0)
- return;
-
- m_GPUDrivenProcessor.enablePartialRendering = false;
- m_GPUDrivenProcessor.EnableGPUDrivenRenderingAndDispatchRendererData(renderersID, m_UpdateRendererDataCallback);
- m_GPUDrivenProcessor.enablePartialRendering = false;
- }
-
- #if UNITY_EDITOR
- public void UpdateSelectedRenderers(NativeArray<int> renderersID)
- {
- var instances = new NativeArray<InstanceHandle>(renderersID.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
- m_BatchersContext.ScheduleQueryRendererGroupInstancesJob(renderersID, instances).Complete();
- m_BatchersContext.UpdateSelectedInstances(instances);
- instances.Dispose();
- }
- #endif
-
- public void PostCullBeginCameraRendering(RenderRequestBatcherContext context)
- {
- m_InstanceCullingBatcher.PostCullBeginCameraRendering(context);
- }
-
- public void OnSetupAmbientProbe()
- {
- m_BatchersContext.UpdateAmbientProbeAndGpuBuffer(forceUpdate: false);
- }
-
- private void UpdateRendererData(in GPUDrivenRendererGroupData rendererData, IList<Mesh> meshes, IList<Material> materials)
- {
- FreeRendererGroupInstances(rendererData.invalidRendererGroupID);
-
- if (rendererData.rendererGroupID.Length == 0)
- return;
-
- Profiler.BeginSample("GPUResidentInstanceBatcher.UpdateRendererData");
- {
- // --------------------------------------------------------------------------------------------------------------------------------------
- // Allocate and Update CPU instance data
- // --------------------------------------------------------------------------------------------------------------------------------------
- var instances = new NativeArray<InstanceHandle>(rendererData.localToWorldMatrix.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory);
-
- Profiler.BeginSample("AllocateInstanceData");
- {
- m_BatchersContext.ReallocateAndGetInstances(rendererData, instances);
- var updateInstanceDataJob = m_BatchersContext.ScheduleUpdateInstanceDataJob(instances, rendererData);
-
- GPUInstanceDataBufferUploader uploader = m_BatchersContext.CreateDataBufferUploader(instances.Length, InstanceType.MeshRenderer);
- uploader.AllocateUploadHandles(instances.Length);
- JobHandle writeJobHandle = default;
- writeJobHandle = uploader.WriteInstanceDataJob(m_BatchersContext.renderersParameters.lightmapScale.index, rendererData.lightmapScaleOffset, rendererData.rendererGroupIndex);
- writeJobHandle.Complete();
-
- m_BatchersContext.SubmitToGpu(instances, ref uploader, submitOnlyWrittenParams: true);
- m_BatchersContext.ChangeInstanceBufferVersion();
- uploader.Dispose();
-
- // --------------------------------------------------------------------------------------------------------------------------------------
- // Update and Upload Transform data to GPU
- // ----------------------------------------------------------------------------------------------------------------------------------
- updateInstanceDataJob.Complete();
- m_BatchersContext.InitializeInstanceTransforms(instances, rendererData.localToWorldMatrix, rendererData.prevLocalToWorldMatrix);
-
- }
- Profiler.EndSample();
-
- // --------------------------------------------------------------------------------------------------------------------------------------
- // Instance culling batcher
- // --------------------------------------------------------------------------------------------------------------------------------------
-
- Profiler.BeginSample("InstanceCullingBatcher.BuildBatch");
- {
- m_InstanceCullingBatcher.BuildBatch(
- instances,
- rendererData.materialID,
- rendererData.meshID,
- rendererData);
-
- }
- Profiler.EndSample();
-
- instances.Dispose();
- }
- Profiler.EndSample();
- }
-
- private void OnFinishedCulling(IntPtr customCullingResult)
- {
- ProcessTrees();
- m_InstanceCullingBatcher.OnFinishedCulling(customCullingResult);
- }
- }
- }
|