A game about forced loneliness, made by TACStudios
at master 99 lines 4.7 kB view raw
1using System; 2using System.Collections.Generic; 3using Unity.Collections; 4using Unity.Jobs; 5using Unity.Jobs.LowLevel.Unsafe; 6using Unity.Burst; 7using UnityEngine.Profiling; 8using Unity.Mathematics; 9using UnityEngine.Assertions; 10 11namespace UnityEngine.Rendering 12{ 13 internal partial class GPUResidentBatcher : IDisposable 14 { 15 private ParallelBitArray m_ProcessedThisFrameTreeBits; 16 17 private void ProcessTrees() 18 { 19 int treeInstancesCount = m_BatchersContext.GetAliveInstancesOfType(InstanceType.SpeedTree); 20 21 if (treeInstancesCount == 0) 22 return; 23 24 ParallelBitArray compactedVisibilityMasks = m_InstanceCullingBatcher.GetCompactedVisibilityMasks(syncCullingJobs: false); 25 26 if (!compactedVisibilityMasks.IsCreated) 27 return; 28 29 Profiler.BeginSample("GPUResidentInstanceBatcher.ProcessTrees"); 30 31 int maxInstancesCount = m_BatchersContext.aliveInstances.Length; 32 33 if(!m_ProcessedThisFrameTreeBits.IsCreated) 34 m_ProcessedThisFrameTreeBits = new ParallelBitArray(maxInstancesCount, Allocator.TempJob); 35 else if(m_ProcessedThisFrameTreeBits.Length < maxInstancesCount) 36 m_ProcessedThisFrameTreeBits.Resize(maxInstancesCount); 37 38 bool becomeVisibleOnly = !Application.isPlaying; 39 var visibleTreeRendererIDs = new NativeList<int>(Allocator.TempJob); 40 var visibleTreeInstances = new NativeList<InstanceHandle>(Allocator.TempJob); 41 42 m_BatchersContext.GetVisibleTreeInstances(compactedVisibilityMasks, m_ProcessedThisFrameTreeBits, visibleTreeRendererIDs, visibleTreeInstances, 43 becomeVisibleOnly, out var becomeVisibleTreeInstancesCount); 44 45 if (visibleTreeRendererIDs.Length > 0) 46 { 47 Profiler.BeginSample("GPUResidentInstanceBatcher.UpdateSpeedTreeWindAndUploadWindParamsToGPU"); 48 49 // Become visible trees is a subset of visible trees. 50 var becomeVisibleTreeRendererIDs = visibleTreeRendererIDs.AsArray().GetSubArray(0, becomeVisibleTreeInstancesCount); 51 var becomeVisibleTreeInstances = visibleTreeInstances.AsArray().GetSubArray(0, becomeVisibleTreeInstancesCount); 52 53 if (becomeVisibleTreeRendererIDs.Length > 0) 54 UpdateSpeedTreeWindAndUploadWindParamsToGPU(becomeVisibleTreeRendererIDs, becomeVisibleTreeInstances, history: true); 55 56 UpdateSpeedTreeWindAndUploadWindParamsToGPU(visibleTreeRendererIDs.AsArray(), visibleTreeInstances.AsArray(), history: false); 57 58 Profiler.EndSample(); 59 } 60 61 visibleTreeRendererIDs.Dispose(); 62 visibleTreeInstances.Dispose(); 63 64 Profiler.EndSample(); 65 } 66 67 private unsafe void UpdateSpeedTreeWindAndUploadWindParamsToGPU(NativeArray<int> treeRendererIDs, NativeArray<InstanceHandle> treeInstances, bool history) 68 { 69 if (treeRendererIDs.Length == 0) 70 return; 71 72 Assert.AreEqual(treeRendererIDs.Length, treeInstances.Length); 73 Assert.AreEqual(m_BatchersContext.renderersParameters.windParams.Length, (int)SpeedTreeWindParamIndex.MaxWindParamsCount); 74 75 var gpuInstanceIndices = new NativeArray<GPUInstanceIndex>(treeInstances.Length, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); 76 m_BatchersContext.instanceDataBuffer.CPUInstanceArrayToGPUInstanceArray(treeInstances, gpuInstanceIndices); 77 78 if (!history) 79 m_BatchersContext.UpdateInstanceWindDataHistory(gpuInstanceIndices); 80 81 GPUInstanceDataBufferUploader uploader = m_BatchersContext.CreateDataBufferUploader(treeInstances.Length, InstanceType.SpeedTree); 82 uploader.AllocateUploadHandles(treeInstances.Length); 83 84 var windParams = new SpeedTreeWindParamsBufferIterator(); 85 windParams.bufferPtr = uploader.GetUploadBufferPtr(); 86 for (int i = 0; i < (int)SpeedTreeWindParamIndex.MaxWindParamsCount; ++i) 87 windParams.uintParamOffsets[i] = uploader.PrepareParamWrite<Vector4>(m_BatchersContext.renderersParameters.windParams[i].index); 88 windParams.uintStride = uploader.GetUIntPerInstance(); 89 windParams.elementOffset = 0; 90 windParams.elementsCount = treeInstances.Length; 91 92 SpeedTreeWindManager.UpdateWindAndWriteBufferWindParams(treeRendererIDs, windParams, history); 93 m_BatchersContext.SubmitToGpu(gpuInstanceIndices, ref uploader, submitOnlyWrittenParams: true); 94 95 gpuInstanceIndices.Dispose(); 96 uploader.Dispose(); 97 } 98 } 99}