Compare commits
merge into: ndepoel:master
ndepoel:2019
ndepoel:cas
ndepoel:framework
ndepoel:fsr3.1.1
ndepoel:fsr3.1.4
ndepoel:fsr3framegen
ndepoel:master
pull from: ndepoel:framework
ndepoel:2019
ndepoel:cas
ndepoel:framework
ndepoel:fsr3.1.1
ndepoel:fsr3.1.4
ndepoel:fsr3framegen
ndepoel:master
24 Commits
42 changed files with 1077 additions and 1094 deletions
-
57Runtime/Common/FfxContextBase.cs
-
11Runtime/Common/FfxContextBase.cs.meta
-
79Runtime/Common/FfxPassBase.cs
-
11Runtime/Common/FfxPassBase.cs.meta
-
96Runtime/Common/FfxResourcesBase.cs
-
11Runtime/Common/FfxResourcesBase.cs.meta
-
46Runtime/Common/FfxSpd.cs
-
11Runtime/Common/FfxSpd.cs.meta
-
118Runtime/Common/FfxUtils.cs
-
11Runtime/Common/FfxUtils.cs.meta
-
90Runtime/FSR2/Fsr2.cs
-
265Runtime/FSR2/Fsr2Context.cs
-
259Runtime/FSR2/Fsr2Pass.cs
-
89Runtime/FSR2/Fsr2Resources.cs
-
90Runtime/FSR3/Fsr3Upscaler.cs
-
1Runtime/FSR3/Fsr3UpscalerAssets.cs
-
295Runtime/FSR3/Fsr3UpscalerContext.cs
-
322Runtime/FSR3/Fsr3UpscalerPass.cs
-
93Runtime/FSR3/Fsr3UpscalerResources.cs
-
4Shaders/ffx_fsr2_accumulate_pass.compute
-
4Shaders/ffx_fsr2_autogen_reactive_pass.compute
-
4Shaders/ffx_fsr2_compute_luminance_pyramid_pass.compute
-
4Shaders/ffx_fsr2_depth_clip_pass.compute
-
4Shaders/ffx_fsr2_lock_pass.compute
-
4Shaders/ffx_fsr2_rcas_pass.compute
-
4Shaders/ffx_fsr2_reconstruct_previous_depth_pass.compute
-
4Shaders/ffx_fsr2_tcr_autogen_pass.compute
-
4Shaders/ffx_fsr3upscaler_accumulate_pass.compute
-
4Shaders/ffx_fsr3upscaler_autogen_reactive_pass.compute
-
4Shaders/ffx_fsr3upscaler_debug_view_pass.compute
-
4Shaders/ffx_fsr3upscaler_luma_instability_pass.compute
-
4Shaders/ffx_fsr3upscaler_luma_pyramid_pass.compute
-
4Shaders/ffx_fsr3upscaler_prepare_inputs_pass.compute
-
4Shaders/ffx_fsr3upscaler_prepare_reactivity_pass.compute
-
4Shaders/ffx_fsr3upscaler_rcas_pass.compute
-
4Shaders/ffx_fsr3upscaler_shading_change_pass.compute
-
4Shaders/ffx_fsr3upscaler_shading_change_pyramid_pass.compute
-
4Shaders/ffx_fsr3upscaler_tcr_autogen_pass.compute
-
12Shaders/ffx_unity_common.cginc
-
0Shaders/ffx_unity_common.cginc.meta
-
48Shaders/shaders/fsr2/ffx_fsr2_callbacks_hlsl.h
-
60Shaders/shaders/fsr3upscaler/ffx_fsr3upscaler_callbacks_hlsl.h
@ -0,0 +1,57 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
public abstract class FfxContextBase |
|||
{ |
|||
protected static void DestroyPass<TPass>(ref TPass pass) |
|||
where TPass: class, IDisposable |
|||
{ |
|||
if (pass == null) |
|||
return; |
|||
|
|||
pass.Dispose(); |
|||
pass = null; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Convenience class for handling a constants buffer containing a single struct item.
|
|||
/// This wraps the compute buffer and the value array, as well as providing easy access to both.
|
|||
/// </summary>
|
|||
protected class ConstantsBuffer<TConst> |
|||
where TConst: struct |
|||
{ |
|||
private ComputeBuffer _computeBuffer; |
|||
|
|||
private readonly TConst[] _constArray = { new TConst() }; |
|||
public ref TConst Value => ref _constArray[0]; |
|||
|
|||
public void Create() |
|||
{ |
|||
_computeBuffer = new ComputeBuffer(1, Marshal.SizeOf<TConst>(), ComputeBufferType.Constant); |
|||
} |
|||
|
|||
public void UpdateBufferData(CommandBuffer commandBuffer) |
|||
{ |
|||
commandBuffer.SetBufferData(_computeBuffer, _constArray); |
|||
} |
|||
|
|||
public void Destroy() |
|||
{ |
|||
if (_computeBuffer == null) |
|||
return; |
|||
|
|||
_computeBuffer.Release(); |
|||
_computeBuffer = null; |
|||
} |
|||
|
|||
public static implicit operator ComputeBuffer(ConstantsBuffer<TConst> constants) |
|||
{ |
|||
return constants._computeBuffer; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: f4aeccbeb6e61434eb2e50b7190fda8d |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,79 @@ |
|||
using System; |
|||
using UnityEngine; |
|||
using UnityEngine.Profiling; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
internal abstract class FfxPassBase: IDisposable |
|||
{ |
|||
private readonly string _techName; |
|||
private string _passName; |
|||
|
|||
protected ComputeShader ComputeShader; |
|||
protected int KernelIndex; |
|||
|
|||
protected FfxPassBase(string techName) |
|||
{ |
|||
_techName = techName; |
|||
} |
|||
|
|||
protected virtual void InitComputeShader(string passName, ComputeShader shader, string kernelName = "CS") |
|||
{ |
|||
if (shader == null) |
|||
{ |
|||
throw new MissingReferenceException($"Shader for {_techName} pass '{passName}' could not be loaded! Please ensure it is included in the project correctly."); |
|||
} |
|||
|
|||
_passName = passName; |
|||
ComputeShader = shader; |
|||
KernelIndex = ComputeShader.FindKernel(kernelName); |
|||
} |
|||
|
|||
public virtual void Dispose() |
|||
{ |
|||
} |
|||
|
|||
protected ProfilerSampler ProfilerSample(CommandBuffer commandBuffer) |
|||
{ |
|||
return new ProfilerSampler(_passName, commandBuffer); |
|||
} |
|||
|
|||
protected readonly struct ProfilerSampler : IDisposable |
|||
{ |
|||
private readonly string _name; |
|||
private readonly CommandBuffer _commandBuffer; |
|||
|
|||
public ProfilerSampler(string name, CommandBuffer commandBuffer) |
|||
{ |
|||
_name = name; |
|||
_commandBuffer = commandBuffer; |
|||
_commandBuffer.BeginSample(_name); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
_commandBuffer.EndSample(_name); |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal abstract class FfxPassWithFlags<TFlags> : FfxPassBase |
|||
where TFlags: Enum |
|||
{ |
|||
protected readonly TFlags Flags; |
|||
|
|||
protected FfxPassWithFlags(string techName, TFlags flags) : base(techName) |
|||
{ |
|||
Flags = flags; |
|||
} |
|||
|
|||
protected override void InitComputeShader(string passName, ComputeShader shader, string kernelName = "CS") |
|||
{ |
|||
base.InitComputeShader(passName, shader, kernelName); |
|||
SetupShaderKeywords(); |
|||
} |
|||
|
|||
protected abstract void SetupShaderKeywords(); |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: deac9cc5a4c6df64db05956030e79425 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,96 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
using UnityEngine.Experimental.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
internal abstract class FfxResourcesBase |
|||
{ |
|||
protected static ComputeBuffer CreateBuffer<TElem>(string name, int count) |
|||
{ |
|||
return new ComputeBuffer(count, Marshal.SizeOf<TElem>()); |
|||
} |
|||
|
|||
protected static Texture2D CreateLookup(string name, GraphicsFormat format, Color data) |
|||
{ |
|||
var tex = new Texture2D(1, 1, format, TextureCreationFlags.None) { name = name }; |
|||
tex.SetPixel(0, 0, data); |
|||
tex.Apply(); |
|||
return tex; |
|||
} |
|||
|
|||
protected static Texture2D CreateLookup<T>(string name, in Vector2Int size, GraphicsFormat format, T[] data) |
|||
{ |
|||
var tex = new Texture2D(size.x, size.y, format, TextureCreationFlags.None) { name = name }; |
|||
tex.SetPixelData(data, 0); |
|||
tex.Apply(); |
|||
return tex; |
|||
} |
|||
|
|||
protected static RenderTexture CreateResource(string name, in Vector2Int size, GraphicsFormat format) |
|||
{ |
|||
var rt = new RenderTexture(size.x, size.y, 0, format) { name = name, enableRandomWrite = true }; |
|||
rt.Create(); |
|||
return rt; |
|||
} |
|||
|
|||
protected static RenderTexture CreateResourceMips(string name, in Vector2Int size, GraphicsFormat format) |
|||
{ |
|||
int mipCount = 1 + Mathf.FloorToInt(Mathf.Log(Math.Max(size.x, size.y), 2.0f)); |
|||
var rt = new RenderTexture(size.x, size.y, 0, format, mipCount) { name = name, enableRandomWrite = true, useMipMap = true, autoGenerateMips = false }; |
|||
rt.Create(); |
|||
return rt; |
|||
} |
|||
|
|||
protected static void CreateDoubleBufferedResource(RenderTexture[] resource, string name, in Vector2Int size, GraphicsFormat format, int numElements = 2) |
|||
{ |
|||
numElements = Math.Min(resource.Length, numElements); |
|||
for (int i = 0; i < numElements; ++i) |
|||
{ |
|||
resource[i] = new RenderTexture(size.x, size.y, 0, format) { name = name + (i + 1), enableRandomWrite = true }; |
|||
resource[i].Create(); |
|||
} |
|||
} |
|||
|
|||
protected static void DestroyResource(ref Texture2D resource) |
|||
{ |
|||
if (resource == null) |
|||
return; |
|||
|
|||
#if UNITY_EDITOR
|
|||
if (Application.isPlaying && !UnityEditor.EditorApplication.isPaused) |
|||
UnityEngine.Object.Destroy(resource); |
|||
else |
|||
UnityEngine.Object.DestroyImmediate(resource); |
|||
#else
|
|||
UnityEngine.Object.Destroy(resource); |
|||
#endif
|
|||
resource = null; |
|||
} |
|||
|
|||
protected static void DestroyResource(ref RenderTexture resource) |
|||
{ |
|||
if (resource == null) |
|||
return; |
|||
|
|||
resource.Release(); |
|||
resource = null; |
|||
} |
|||
|
|||
protected static void DestroyResource(ref ComputeBuffer resource) |
|||
{ |
|||
if (resource == null) |
|||
return; |
|||
|
|||
resource.Release(); |
|||
resource = null; |
|||
} |
|||
|
|||
protected static void DestroyResource(RenderTexture[] resource) |
|||
{ |
|||
for (int i = 0; i < resource.Length; ++i) |
|||
DestroyResource(ref resource[i]); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 2a46b97ac72c45545a80a896462e1112 |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
public static class FfxSpd |
|||
{ |
|||
public static void SetupSpdConstants(Vector2Int resolution, ref SpdConstants spdConstants, out Vector2Int dispatchThreadGroupCount, int mips = -1) |
|||
{ |
|||
RectInt rectInfo = new RectInt(0, 0, resolution.x, resolution.y); |
|||
SpdSetup(rectInfo, out dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, mips); |
|||
|
|||
spdConstants.numWorkGroups = (uint)numWorkGroupsAndMips.x; |
|||
spdConstants.mips = (uint)numWorkGroupsAndMips.y; |
|||
spdConstants.workGroupOffsetX = (uint)workGroupOffset.x; |
|||
spdConstants.workGroupOffsetY = (uint)workGroupOffset.y; |
|||
} |
|||
|
|||
public static void SpdSetup(RectInt rectInfo, out Vector2Int dispatchThreadGroupCount, out Vector2Int workGroupOffset, out Vector2Int numWorkGroupsAndMips, int mips = -1) |
|||
{ |
|||
workGroupOffset = new Vector2Int(rectInfo.x / 64, rectInfo.y / 64); |
|||
|
|||
int endIndexX = (rectInfo.x + rectInfo.width - 1) / 64; |
|||
int endIndexY = (rectInfo.y + rectInfo.height - 1) / 64; |
|||
|
|||
dispatchThreadGroupCount = new Vector2Int(endIndexX + 1 - workGroupOffset.x, endIndexY + 1 - workGroupOffset.y); |
|||
|
|||
numWorkGroupsAndMips = new Vector2Int(dispatchThreadGroupCount.x * dispatchThreadGroupCount.y, mips); |
|||
if (mips < 0) |
|||
{ |
|||
float resolution = Math.Max(rectInfo.width, rectInfo.height); |
|||
numWorkGroupsAndMips.y = Math.Min(Mathf.FloorToInt(Mathf.Log(resolution, 2.0f)), 12); |
|||
} |
|||
} |
|||
|
|||
[Serializable, StructLayout(LayoutKind.Sequential)] |
|||
public struct SpdConstants |
|||
{ |
|||
public uint mips; |
|||
public uint numWorkGroups; |
|||
public uint workGroupOffsetX; |
|||
public uint workGroupOffsetY; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: aee0f42dc1676ab4db5c01520b0b925a |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
@ -0,0 +1,118 @@ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
using UnityEngine; |
|||
using UnityEngine.Rendering; |
|||
|
|||
namespace FidelityFX |
|||
{ |
|||
public static class FfxUtils |
|||
{ |
|||
public static float GetMipmapBiasOffset(int renderWidth, int displayWidth) |
|||
{ |
|||
return Mathf.Log((float)renderWidth / displayWidth, 2.0f) - 1.0f; |
|||
} |
|||
|
|||
public static int GetJitterPhaseCount(int renderWidth, int displayWidth) |
|||
{ |
|||
const float basePhaseCount = 8.0f; |
|||
int jitterPhaseCount = (int)(basePhaseCount * Mathf.Pow((float)displayWidth / renderWidth, 2.0f)); |
|||
return jitterPhaseCount; |
|||
} |
|||
|
|||
public static void GetJitterOffset(out float outX, out float outY, int index, int phaseCount) |
|||
{ |
|||
outX = Halton((index % phaseCount) + 1, 2) - 0.5f; |
|||
outY = Halton((index % phaseCount) + 1, 3) - 0.5f; |
|||
} |
|||
|
|||
// Calculate halton number for index and base.
|
|||
private static float Halton(int index, int @base) |
|||
{ |
|||
float f = 1.0f, result = 0.0f; |
|||
|
|||
for (int currentIndex = index; currentIndex > 0;) { |
|||
|
|||
f /= @base; |
|||
result += f * (currentIndex % @base); |
|||
currentIndex = (int)Mathf.Floor((float)currentIndex / @base); |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
public static float Lanczos2(float value) |
|||
{ |
|||
return Mathf.Abs(value) < Mathf.Epsilon ? 1.0f : Mathf.Sin(Mathf.PI * value) / (Mathf.PI * value) * (Mathf.Sin(0.5f * Mathf.PI * value) / (0.5f * Mathf.PI * value)); |
|||
} |
|||
|
|||
public static float[] GenerateLanczos2Table(int width) |
|||
{ |
|||
float[] lanczos2Weights = new float[width]; |
|||
for (int currentLanczosWidthIndex = 0; currentLanczosWidthIndex < width; ++currentLanczosWidthIndex) |
|||
{ |
|||
float x = 2.0f * currentLanczosWidthIndex / (width - 1); |
|||
float y = Lanczos2(x); |
|||
lanczos2Weights[currentLanczosWidthIndex] = y; |
|||
} |
|||
|
|||
return lanczos2Weights; |
|||
} |
|||
|
|||
public static Vector4 SetupDeviceDepthToViewSpaceDepthParams(Vector2Int renderSize, float cameraNear, float cameraFar, float cameraFovAngleVertical, bool inverted, bool infinite) |
|||
{ |
|||
// make sure it has no impact if near and far plane values are swapped in dispatch params
|
|||
// the flags "inverted" and "infinite" will decide what transform to use
|
|||
float min = Mathf.Min(cameraNear, cameraFar); |
|||
float max = Mathf.Max(cameraNear, cameraFar); |
|||
|
|||
if (inverted) |
|||
{ |
|||
(min, max) = (max, min); |
|||
} |
|||
|
|||
float q = max / (min - max); |
|||
float d = -1.0f; |
|||
|
|||
Vector4 matrixElemC = new Vector4(q, -1.0f - Mathf.Epsilon, q, 0.0f + Mathf.Epsilon); |
|||
Vector4 matrixElemE = new Vector4(q * min, -min - Mathf.Epsilon, q * min, max); |
|||
|
|||
// Revert x and y coords
|
|||
float aspect = (float)renderSize.x / renderSize.y; |
|||
float cotHalfFovY = Mathf.Cos(0.5f * cameraFovAngleVertical) / Mathf.Sin(0.5f * cameraFovAngleVertical); |
|||
|
|||
int matrixIndex = (inverted ? 2 : 0) + (infinite ? 1 : 0); |
|||
return new Vector4( |
|||
d * matrixElemC[matrixIndex], |
|||
matrixElemE[matrixIndex], |
|||
aspect / cotHalfFovY, |
|||
1.0f / cotHalfFovY); |
|||
} |
|||
|
|||
#if !UNITY_2021_1_OR_NEWER
|
|||
internal static void SetBufferData(this CommandBuffer commandBuffer, ComputeBuffer computeBuffer, Array data) |
|||
{ |
|||
commandBuffer.SetComputeBufferData(computeBuffer, data); |
|||
} |
|||
#endif
|
|||
|
|||
/// <summary>
|
|||
/// Alternative for CommandBuffer.SetComputeTextureParam that guards against attempts to bind mip levels that don't exist.
|
|||
/// </summary>
|
|||
internal static void SetComputeTextureMipParam(this CommandBuffer commandBuffer, ComputeShader computeShader, int kernelIndex, int nameID, Texture texture, int mipLevel) |
|||
{ |
|||
mipLevel = Math.Min(mipLevel, texture.mipmapCount - 1); |
|||
commandBuffer.SetComputeTextureParam(computeShader, kernelIndex, nameID, texture, mipLevel); |
|||
} |
|||
|
|||
internal static void SetComputeResourceParam(this CommandBuffer commandBuffer, ComputeShader computeShader, int kernelIndex, int nameID, in ResourceView resource) |
|||
{ |
|||
commandBuffer.SetComputeTextureParam(computeShader, kernelIndex, nameID, resource.RenderTarget, resource.MipLevel, resource.SubElement); |
|||
} |
|||
|
|||
internal static void SetComputeConstantBufferParam<TBuf>(this CommandBuffer commandBuffer, ComputeShader computeShader, int nameID, ComputeBuffer buffer) |
|||
where TBuf: struct |
|||
{ |
|||
commandBuffer.SetComputeConstantBufferParam(computeShader, nameID, buffer, 0, Marshal.SizeOf<TBuf>()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
fileFormatVersion: 2 |
|||
guid: 9c5c0f0b987cca64c8dfd8051e09962e |
|||
MonoImporter: |
|||
externalObjects: {} |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue