namespace UnityEngine.Rendering
{
///
/// User API to request access for an instance of the user history type.
/// Tracks the history types that were requested by the render pipeline features on this frame.
/// Requested history types are then made available for the future frames.
/// Request is active for one frame only and a new request should be made every frame.
/// Types that were not requested are eventually reset and GPU resources released.
///
public interface IPerFrameHistoryAccessTracker
{
///
/// Mark a certain history texture type (class) as a requirement for next frame.
/// Note: Requesting a history doesn't mean it will be actually available.
/// E.g. The first frame doesn't have any history data available at all.
///
/// Type of the history instance.
public void RequestAccess() where Type : ContextItem;
}
///
/// User API to get history write access for a user history type instance.
/// Write access is valid and available after the history type has been requested.
/// Otherwise a null is returned.
/// Typically called by the history type producer render pass in the render pipeline.
///
public interface ICameraHistoryWriteAccess
{
///
/// Check if a type has been requested and should be written this frame.
///
/// Type of the history instance.
/// True if a type has been requested earlier. False otherwise.
public bool IsAccessRequested() where Type : ContextItem;
///
/// Get write access to an instance of certain history type.
/// It is expected that the caller will filling the contents of the type textures.
/// Null if not requested beforehand.
/// On first get of a type, the type instance is created.
///
/// Type of the history instance.
/// True if a type has been requested earlier. False otherwise.
public Type GetHistoryForWrite() where Type : ContextItem, new();
///
/// Check if a type was already written this frame by some render pass.
///
/// Type of the history instance.
/// True if a type has been written earlier. False otherwise.
public bool IsWritten() where Type : ContextItem;
}
///
/// User API to get history read access for a user history type instance.
/// Read access is valid and available after the history type has been requested and written by a render pass.
/// Otherwise a null is returned.
/// Typically called by the history type consumer render pass in the render pipeline.
///
/// User API for external systems to register history read access callbacks.
///
public interface ICameraHistoryReadAccess
{
///
/// Get read access to an instance of certain history type.
/// Available only if the type instance has been requested and written earlier.
///
/// Type of the history instance.
/// A class instance of Type. Null if not available on this frame.
// Get a certain history item from the camera or null if not available this frame.
public Type GetHistoryForRead() where Type : ContextItem;
///
/// Callback type for requesting various history type instances for read.
/// Typically used by systems external to the pipeline.
/// For example: A MonoBehavior requesting access for MonoBehavior.LateUpdate() call.
///
/// A container for history type requests.
public delegate void HistoryRequestDelegate(IPerFrameHistoryAccessTracker historyAccess);
///
/// A callback event used to register a callback for requesting history types.
///
public event HistoryRequestDelegate OnGatherHistoryRequests;
}
///
/// A convenience base class for camera history items/types.
/// It is recommended to derive from this class to make new history item type.
///
/// The owning camera BufferedRTHandleSystem reference is used for central storage.
/// The central storage allows the camera to track all of the history types in a single place.
/// And gives the deriving type a direct access to texture allocation services.
/// Type id is used to deconflict RTHandle ids from different types.
///
/// The user is responsible for designing the derived type to work well with the
/// producing and consuming render passes.
/// For example:
/// Add the necessary cpu-side tracking data and update logic.
/// Add methods for accessing the history data and design a suitable API for the type.
/// Handle allocation and deallocation of the history texture RTHandles etc.
///
public abstract class CameraHistoryItem : ContextItem
{
// BufferedRTHandleSystem of the owning camera.
private BufferedRTHandleSystem m_owner = null;
// Unique id for this type (derived) given by the owning camera.
private uint m_TypeId = uint.MaxValue;
///
/// Called internally when a CameraHistoryItem type is created to initialize the RTHandle storage and type id.
///
/// User types can override to do additional initialization, such as creating the ids for multiple history RTHandles.
/// Deriving type should call the base.OnCreate() to correctly initialize the CameraHistoryItem first.
///
/// BufferedRTHandleSystem of the owning camera.
/// Unique id given to this class type by the owning camera.
public virtual void OnCreate(BufferedRTHandleSystem owner, uint typeId)
{
m_owner = owner;
m_TypeId = typeId;
}
// The user API is protected, so that the BufferedRTHandleSystem is visible only for the custom Type implementation.
///
/// The owning camera RTHandle storage for the history textures.
///
protected BufferedRTHandleSystem storage => m_owner;
///
/// Creates unique ids for the RTHandle storage.
/// Index == 0, returns the TypeId of this CameraHistoryItem.
/// Index == N, generates new ids in case the user wants to store multiple history textures in the same CameraHistoryItem.
///
/// Index of the type RTHandle, a type local Enum or a user id.
/// A unique id for each type, index and camera.
protected int MakeId(uint index)
{
return (int)(((m_TypeId & 0xFFFF) << 16) | (index & 0xFFFF));
}
///
/// Allocate a history frame RTHandle[] using a descriptor.
///
/// Id for the history RTHandle storage.
/// Number of RTHandles allocated for the id.
/// Texture descriptor used for each RTHandle in the allocation.
/// User visible debug name of the texture.
/// Current frame RTHandle in the allocation.
protected RTHandle AllocHistoryFrameRT(int id, int count,
ref RenderTextureDescriptor desc, string name = "")
{
RenderTextureDescriptor d = desc;
// Simplified for typical history textures:
// Sampling is usually bilinear & clamp. Point sample can be a texture.Load() or done with inline samplers.
// No shadows, no mipmaps, no aniso.
m_owner.AllocBuffer(id, count, ref desc, FilterMode.Bilinear, TextureWrapMode.Clamp, false, 0, 0, name);
return GetCurrentFrameRT(0);
}
///
/// Release the RTHandles allocated for the id.
///
/// Id for the history RTHandle storage.
protected void ReleaseHistoryFrameRT(int id)
{
m_owner.ReleaseBuffer(id);
}
///
/// Returns the id RTHandle from the previous frame.
///
/// Id for the history RTHandle storage.
/// The RTHandle from previous frame.
protected RTHandle GetPreviousFrameRT(int id)
{
return m_owner.GetFrameRT(id, 1);
}
///
/// Returns the id RTHandle of the current frame.
///
/// Id for the history RTHandle storage.
/// The RTHandle of the current frame.
protected RTHandle GetCurrentFrameRT(int id)
{
return m_owner.GetFrameRT(id, 0);
}
}
}