A game about forced loneliness, made by TACStudios
at master 191 lines 9.4 kB view raw
1namespace UnityEngine.Rendering 2{ 3 /// <summary> 4 /// User API to request access for an instance of the user history type. 5 /// Tracks the history types that were requested by the render pipeline features on this frame. 6 /// Requested history types are then made available for the future frames. 7 /// Request is active for one frame only and a new request should be made every frame. 8 /// Types that were not requested are eventually reset and GPU resources released. 9 /// </summary> 10 public interface IPerFrameHistoryAccessTracker 11 { 12 /// <summary> 13 /// Mark a certain history texture type (class) as a requirement for next frame. 14 /// Note: Requesting a history doesn't mean it will be actually available. 15 /// E.g. The first frame doesn't have any history data available at all. 16 /// </summary> 17 /// <typeparam name="Type">Type of the history instance.</typeparam> 18 public void RequestAccess<Type>() where Type : ContextItem; 19 } 20 21 /// <summary> 22 /// User API to get history write access for a user history type instance. 23 /// Write access is valid and available after the history type has been requested. 24 /// Otherwise a null is returned. 25 /// Typically called by the history type producer render pass in the render pipeline. 26 /// </summary> 27 public interface ICameraHistoryWriteAccess 28 { 29 /// <summary> 30 /// Check if a type has been requested and should be written this frame. 31 /// </summary> 32 /// <typeparam name="Type">Type of the history instance.</typeparam> 33 /// <returns>True if a type has been requested earlier. False otherwise.</returns> 34 public bool IsAccessRequested<Type>() where Type : ContextItem; 35 36 /// <summary> 37 /// Get write access to an instance of certain history type. 38 /// It is expected that the caller will filling the contents of the type textures. 39 /// Null if not requested beforehand. 40 /// On first get of a type, the type instance is created. 41 /// </summary> 42 /// <typeparam name="Type">Type of the history instance.</typeparam> 43 /// <returns>True if a type has been requested earlier. False otherwise.</returns> 44 public Type GetHistoryForWrite<Type>() where Type : ContextItem, new(); 45 46 /// <summary> 47 /// Check if a type was already written this frame by some render pass. 48 /// </summary> 49 /// <typeparam name="Type">Type of the history instance.</typeparam> 50 /// <returns>True if a type has been written earlier. False otherwise.</returns> 51 public bool IsWritten<Type>() where Type : ContextItem; 52 } 53 54 /// <summary> 55 /// User API to get history read access for a user history type instance. 56 /// Read access is valid and available after the history type has been requested and written by a render pass. 57 /// Otherwise a null is returned. 58 /// Typically called by the history type consumer render pass in the render pipeline. 59 /// 60 /// User API for external systems to register history read access callbacks. 61 /// </summary> 62 public interface ICameraHistoryReadAccess 63 { 64 /// <summary> 65 /// Get read access to an instance of certain history type. 66 /// Available only if the type instance has been requested and written earlier. 67 /// </summary> 68 /// <typeparam name="Type">Type of the history instance.</typeparam> 69 /// <returns>A class instance of Type. Null if not available on this frame.</returns> 70 // Get a certain history item from the camera or null if not available this frame. 71 public Type GetHistoryForRead<Type>() where Type : ContextItem; 72 73 /// <summary> 74 /// Callback type for requesting various history type instances for read. 75 /// Typically used by systems external to the pipeline. 76 /// For example: A MonoBehavior requesting access for MonoBehavior.LateUpdate() call. 77 /// </summary> 78 /// <param name="historyAccess">A container for history type requests.</param> 79 public delegate void HistoryRequestDelegate(IPerFrameHistoryAccessTracker historyAccess); 80 81 /// <summary> 82 /// A callback event used to register a callback for requesting history types. 83 /// </summary> 84 public event HistoryRequestDelegate OnGatherHistoryRequests; 85 } 86 87 /// <summary> 88 /// A convenience base class for camera history items/types. 89 /// It is recommended to derive from this class to make new history item type. 90 /// 91 /// The owning camera BufferedRTHandleSystem reference is used for central storage. 92 /// The central storage allows the camera to track all of the history types in a single place. 93 /// And gives the deriving type a direct access to texture allocation services. 94 /// Type id is used to deconflict RTHandle ids from different types. 95 /// 96 /// The user is responsible for designing the derived type to work well with the 97 /// producing and consuming render passes. 98 /// For example: 99 /// Add the necessary cpu-side tracking data and update logic. 100 /// Add methods for accessing the history data and design a suitable API for the type. 101 /// Handle allocation and deallocation of the history texture RTHandles etc. 102 /// </summary> 103 public abstract class CameraHistoryItem : ContextItem 104 { 105 // BufferedRTHandleSystem of the owning camera. 106 private BufferedRTHandleSystem m_owner = null; 107 // Unique id for this type (derived) given by the owning camera. 108 private uint m_TypeId = uint.MaxValue; 109 110 /// <summary> 111 /// Called internally when a CameraHistoryItem type is created to initialize the RTHandle storage and type id. 112 /// 113 /// User types can override to do additional initialization, such as creating the ids for multiple history RTHandles. 114 /// Deriving type should call the base.OnCreate() to correctly initialize the CameraHistoryItem first. 115 /// </summary> 116 /// <param name="owner">BufferedRTHandleSystem of the owning camera.</param> 117 /// <param name="typeId">Unique id given to this class type by the owning camera.</param> 118 public virtual void OnCreate(BufferedRTHandleSystem owner, uint typeId) 119 { 120 m_owner = owner; 121 m_TypeId = typeId; 122 } 123 124 // The user API is protected, so that the BufferedRTHandleSystem is visible only for the custom Type implementation. 125 126 /// <summary> 127 /// The owning camera RTHandle storage for the history textures. 128 /// </summary> 129 protected BufferedRTHandleSystem storage => m_owner; 130 131 /// <summary> 132 /// Creates unique ids for the RTHandle storage. 133 /// Index == 0, returns the TypeId of this CameraHistoryItem. 134 /// Index == N, generates new ids in case the user wants to store multiple history textures in the same CameraHistoryItem. 135 /// </summary> 136 /// <param name="index">Index of the type RTHandle, a type local Enum or a user id.</param> 137 /// <returns>A unique id for each type, index and camera.</returns> 138 protected int MakeId(uint index) 139 { 140 return (int)(((m_TypeId & 0xFFFF) << 16) | (index & 0xFFFF)); 141 } 142 143 /// <summary> 144 /// Allocate a history frame RTHandle[] using a descriptor. 145 /// </summary> 146 /// <param name="id">Id for the history RTHandle storage.</param> 147 /// <param name="count">Number of RTHandles allocated for the id.</param> 148 /// <param name="desc">Texture descriptor used for each RTHandle in the allocation.</param> 149 /// <param name="name">User visible debug name of the texture.</param> 150 /// <returns>Current frame RTHandle in the allocation.</returns> 151 protected RTHandle AllocHistoryFrameRT(int id, int count, 152 ref RenderTextureDescriptor desc, string name = "") 153 { 154 RenderTextureDescriptor d = desc; 155 // Simplified for typical history textures: 156 // Sampling is usually bilinear & clamp. Point sample can be a texture.Load() or done with inline samplers. 157 // No shadows, no mipmaps, no aniso. 158 m_owner.AllocBuffer(id, count, ref desc, FilterMode.Bilinear, TextureWrapMode.Clamp, false, 0, 0, name); 159 return GetCurrentFrameRT(0); 160 } 161 162 /// <summary> 163 /// Release the RTHandles allocated for the id. 164 /// </summary> 165 /// <param name="id">Id for the history RTHandle storage.</param> 166 protected void ReleaseHistoryFrameRT(int id) 167 { 168 m_owner.ReleaseBuffer(id); 169 } 170 171 /// <summary> 172 /// Returns the id RTHandle from the previous frame. 173 /// </summary> 174 /// <param name="id">Id for the history RTHandle storage.</param> 175 /// <returns>The RTHandle from previous frame.</returns> 176 protected RTHandle GetPreviousFrameRT(int id) 177 { 178 return m_owner.GetFrameRT(id, 1); 179 } 180 181 /// <summary> 182 /// Returns the id RTHandle of the current frame. 183 /// </summary> 184 /// <param name="id">Id for the history RTHandle storage.</param> 185 /// <returns>The RTHandle of the current frame.</returns> 186 protected RTHandle GetCurrentFrameRT(int id) 187 { 188 return m_owner.GetFrameRT(id, 0); 189 } 190 } 191}