A game about forced loneliness, made by TACStudios
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}