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.
 
 
 
 

148 lines
5.3 KiB

#if ENABLE_UPSCALER_FRAMEWORK
#nullable enable
using System;
using System.Collections.Generic;
namespace UnityEngine.Rendering
{
public static class UpscalerRegistry
{
public static readonly Dictionary<Type, (Type? OptionsType, string ID)> s_RegisteredUpscalers = new();
/// <summary>
/// Registers an IUpscaler type without any custom options type.
/// </summary>
public static void Register<TUpscaler>(string id) where TUpscaler : IUpscaler, new()
{
s_RegisteredUpscalers[typeof(TUpscaler)] = (null, id);
}
/// <summary>
/// Registers an IUpscaler type with its custom options type.
/// </summary>
public static void Register<TUpscaler, TOptions>(string id)
where TUpscaler : IUpscaler
where TOptions : UpscalerOptions
{
s_RegisteredUpscalers[typeof(TUpscaler)] = (typeof(TOptions), id);
}
}
public class Upscaling
{
public List<IUpscaler> upscalers = new();
public string[] upscalerNames { get; }
private int activeUpscalerIndex = -1;
/// <summary>
/// Initializes the Upscaling system with the given list of upscaler options per upscaler type.
/// </summary>
public Upscaling(List<UpscalerOptions> RPAssetUpscalerOptionsList)
{
foreach (var kvp in UpscalerRegistry.s_RegisteredUpscalers)
{
Type upscalerType = kvp.Key;
Type? optionsType = kvp.Value.OptionsType;
// find any serialized options, if any provided by the package implementor
int optionsIndex = RPAssetUpscalerOptionsList.FindIndex(o => o != null && o.GetType() == optionsType);
bool optionsNotFound = optionsIndex == -1;
UpscalerOptions? options = optionsNotFound ? null: RPAssetUpscalerOptionsList[optionsIndex];
// construct upscaler
IUpscaler upscaler = optionsType != null
? (IUpscaler)Activator.CreateInstance(upscalerType, new object[] { options! })
: (IUpscaler)Activator.CreateInstance(upscalerType);
if(options != null && string.IsNullOrEmpty(options.UpscalerName))
{
string upscalerName = upscaler.GetName();
Debug.LogWarningFormat("[Upscaling] UpscalerOptions with empty UpscalerName for {0}", upscalerName);
options.UpscalerName = upscalerName;
}
upscalers.Add(upscaler);
}
// Get upscaler names
upscalerNames = new string[upscalers.Count];
for (int i = 0; i < upscalers.Count; i++)
{
upscalerNames[i] = upscalers[i].GetName();
}
}
/// <summary>
/// Returns the IUpscaler at the given index.
/// </summary>
public IUpscaler GetUpscalerAtIndex(int index)
{
Debug.Assert(index >= 0 && index < upscalers.Count);
return upscalers[index];
}
/// <summary>
/// Returns whether an upscaler with the given name was found.
/// </summary>
public bool SetActiveUpscaler(string name)
{
// TODO (Apoorva): We need to allow the IUpscaler itself to decide whether it can run. E.g.
// DLSS might need a certain version of Windows, and a compatible GPU. We should add an
// overrideable function to IUpscaler so that the active IUpscaler can return a bool
// indicating support.
bool found = false;
for (int i = 0; i < upscalerNames.Length; i++)
{
if (upscalerNames[i] == name)
{
activeUpscalerIndex = i;
found = true;
break;
}
}
return found;
}
/// <summary>
/// Returns null if no IUpscaler is active
/// </summary>
public IUpscaler? GetActiveUpscaler()
{
if (activeUpscalerIndex == -1)
return null;
return GetUpscalerAtIndex(activeUpscalerIndex);
}
/// <summary>
/// Returns null if no IUpscaler exists for given type
/// </summary>
public IUpscaler? GetIUpscalerOfType<T>() where T : IUpscaler
{
if(!UpscalerRegistry.s_RegisteredUpscalers.ContainsKey(typeof(T)))
return null;
foreach (IUpscaler upscaler in upscalers)
if (upscaler.GetType() == typeof(T))
return upscaler;
Debug.LogErrorFormat($"Upscaler type {typeof(T)} not found");
return null;
}
/// <summary>
/// Returns null if no IUpscaler exists for given type
/// </summary>
public IUpscaler? GetIUpscalerOfType(Type T)
{
if (!UpscalerRegistry.s_RegisteredUpscalers.ContainsKey(T))
return null;
foreach (IUpscaler upscaler in upscalers)
if (upscaler.GetType() == T)
return upscaler;
Debug.LogErrorFormat($"Upscaler type {T} not found");
return null;
}
}
}
#endif