Bez popisu
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

GPUResidentBatcher.SpeedTree.cs 4.6KB

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