diff --git a/Runtime/FSR2/Fsr2Context.cs b/Runtime/FSR2/Fsr2Context.cs index 5b0b238..cd02699 100644 --- a/Runtime/FSR2/Fsr2Context.cs +++ b/Runtime/FSR2/Fsr2Context.cs @@ -163,7 +163,7 @@ namespace FidelityFX.FSR2 // If auto exposure is enabled use the auto exposure SRV, otherwise what the app sends if ((_contextDescription.Flags & Fsr2.InitializationFlags.EnableAutoExposure) != 0) - dispatchParams.Exposure = new ResourceView(_resources.AutoExposure); + dispatchParams.Exposure = new ResourceView(_resources.AutoExposure[frameIndex]); else if (!dispatchParams.Exposure.IsValid) dispatchParams.Exposure = new ResourceView(_resources.DefaultExposure); @@ -211,8 +211,8 @@ namespace FidelityFX.FSR2 commandBuffer.ClearRenderTarget(false, true, Color.clear); // Auto exposure always used to track luma changes in locking logic - commandBuffer.SetRenderTarget(_resources.AutoExposure); - commandBuffer.ClearRenderTarget(false, true, new Color(0f, 1f, 0f, 0f)); + commandBuffer.SetRenderTarget(_resources.AutoExposure[frameIndex ^ 1]); + commandBuffer.ClearRenderTarget(false, true, new Color(0f, 1e8f, 0f, 0f)); // Reset atomic counter to 0 commandBuffer.SetRenderTarget(_resources.SpdAtomicCounter); diff --git a/Runtime/FSR2/Fsr2Pass.cs b/Runtime/FSR2/Fsr2Pass.cs index 94ef9e5..d791f79 100644 --- a/Runtime/FSR2/Fsr2Pass.cs +++ b/Runtime/FSR2/Fsr2Pass.cs @@ -127,11 +127,12 @@ namespace FidelityFX.FSR2 { ref var color = ref dispatchParams.Color; commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvInputColor, color.RenderTarget, color.MipLevel, color.SubElement); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvAutoExposure, Resources.AutoExposure[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavSpdAtomicCount, Resources.SpdAtomicCounter); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMipLumaChange, Resources.SceneLuminance, ShadingChangeMipLevel); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavExposureMip5, Resources.SceneLuminance, 5); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoExposure, Resources.AutoExposure); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavAutoExposure, Resources.AutoExposure[frameIndex]); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbFsr2, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, Fsr2ShaderIDs.CbSpd, _spdConstants, 0, Marshal.SizeOf()); @@ -271,7 +272,7 @@ namespace FidelityFX.FSR2 commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvLanczosLut, Resources.LanczosLut); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvUpscaleMaximumBiasLut, Resources.MaximumBiasLut); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvSceneLuminanceMips, Resources.SceneLuminance); - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvAutoExposure, Resources.AutoExposure); + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvAutoExposure, Resources.AutoExposure[frameIndex]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.SrvLumaHistory, Resources.LumaHistory[frameIndex ^ 1]); commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, Fsr2ShaderIDs.UavInternalUpscaled, Resources.InternalUpscaled[frameIndex]); diff --git a/Runtime/FSR2/Fsr2Resources.cs b/Runtime/FSR2/Fsr2Resources.cs index 4c1c50e..39a7120 100644 --- a/Runtime/FSR2/Fsr2Resources.cs +++ b/Runtime/FSR2/Fsr2Resources.cs @@ -36,10 +36,10 @@ namespace FidelityFX.FSR2 public Texture2D LanczosLut; public Texture2D MaximumBiasLut; public RenderTexture SpdAtomicCounter; - public RenderTexture AutoExposure; public RenderTexture SceneLuminance; public RenderTexture AutoReactive; public RenderTexture AutoComposition; + public readonly RenderTexture[] AutoExposure = new RenderTexture[2]; public readonly RenderTexture[] DilatedMotionVectors = new RenderTexture[2]; public readonly RenderTexture[] LockStatus = new RenderTexture[2]; public readonly RenderTexture[] InternalUpscaled = new RenderTexture[2]; @@ -91,10 +91,6 @@ namespace FidelityFX.FSR2 SpdAtomicCounter = new RenderTexture(1, 1, 0, GraphicsFormat.R32_UInt) { name = "FSR2_SpdAtomicCounter", enableRandomWrite = true }; SpdAtomicCounter.Create(); - // Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE - AutoExposure = new RenderTexture(1, 1, 0, GraphicsFormat.R32G32_SFloat) { name = "FSR2_AutoExposure", enableRandomWrite = true }; - AutoExposure.Create(); - // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE // This is a rather special case: it's an aliasable resource, but because we require a mipmap chain and bind specific mip levels per shader, we can't easily use temporary RTs for this. int w = contextDescription.MaxRenderSize.x / 2, h = contextDescription.MaxRenderSize.y / 2; @@ -102,6 +98,9 @@ namespace FidelityFX.FSR2 SceneLuminance = new RenderTexture(w, h, 0, GraphicsFormat.R16_SFloat, mipCount) { name = "FSR2_ExposureMips", enableRandomWrite = true, useMipMap = true, autoGenerateMips = false }; SceneLuminance.Create(); + // Resource FSR2_AutoExposure: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32G32_FLOAT, FFX_RESOURCE_FLAGS_NONE + CreateDoubleBufferedResource(AutoExposure, "FSR2_AutoExposure", Vector2Int.one, GraphicsFormat.R32G32_SFloat); + // Resources FSR2_InternalDilatedVelocity1/2: FFX_RESOURCE_USAGE_RENDERTARGET | FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16G16_FLOAT, FFX_RESOURCE_FLAGS_NONE CreateDoubleBufferedResource(DilatedMotionVectors, "FSR2_InternalDilatedVelocity", contextDescription.MaxRenderSize, GraphicsFormat.R16G16_SFloat); @@ -186,8 +185,8 @@ namespace FidelityFX.FSR2 DestroyResource(InternalUpscaled); DestroyResource(LockStatus); DestroyResource(DilatedMotionVectors); + DestroyResource(AutoExposure); DestroyResource(ref SceneLuminance); - DestroyResource(ref AutoExposure); DestroyResource(ref DefaultReactive); DestroyResource(ref DefaultExposure); DestroyResource(ref MaximumBiasLut); diff --git a/Shaders/shaders/ffx_fsr2_compute_luminance_pyramid_pass.hlsl b/Shaders/shaders/ffx_fsr2_compute_luminance_pyramid_pass.hlsl index 31de05f..08fe456 100644 --- a/Shaders/shaders/ffx_fsr2_compute_luminance_pyramid_pass.hlsl +++ b/Shaders/shaders/ffx_fsr2_compute_luminance_pyramid_pass.hlsl @@ -21,6 +21,7 @@ // THE SOFTWARE. #define FSR2_BIND_SRV_INPUT_COLOR 0 +#define FSR2_BIND_SRV_AUTO_EXPOSURE 1 #define FSR2_BIND_UAV_SPD_GLOBAL_ATOMIC 0 #define FSR2_BIND_UAV_EXPOSURE_MIP_LUMA_CHANGE 1 diff --git a/Shaders/shaders/fsr2/ffx_fsr2_callbacks_hlsl.h b/Shaders/shaders/fsr2/ffx_fsr2_callbacks_hlsl.h index 9007343..25d8e52 100644 --- a/Shaders/shaders/fsr2/ffx_fsr2_callbacks_hlsl.h +++ b/Shaders/shaders/fsr2/ffx_fsr2_callbacks_hlsl.h @@ -908,7 +908,9 @@ void StorePrevPostAlpha(FFX_PARAMETER_IN FFX_MIN16_I2 iPxPos, FFX_PARAMETER_IN F FfxFloat32x2 SPD_LoadExposureBuffer() { -#if defined FSR2_BIND_UAV_AUTO_EXPOSURE +#if defined FSR2_BIND_SRV_AUTO_EXPOSURE + return r_auto_exposure[FfxInt32x2(0, 0)]; +#elif defined FSR2_BIND_UAV_AUTO_EXPOSURE return rw_auto_exposure[FfxInt32x2(0, 0)]; #else return FfxFloat32x2(0.f, 0.f); diff --git a/Shaders/shaders/fsr2/ffx_fsr2_compute_luminance_pyramid.h b/Shaders/shaders/fsr2/ffx_fsr2_compute_luminance_pyramid.h index a0e74b0..62b9899 100644 --- a/Shaders/shaders/fsr2/ffx_fsr2_compute_luminance_pyramid.h +++ b/Shaders/shaders/fsr2/ffx_fsr2_compute_luminance_pyramid.h @@ -20,7 +20,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. -FFX_GROUPSHARED FfxUInt32 spdCounter; +FFX_GROUPSHARED FfxUInt32 spdCounter = 0u; void SpdIncreaseAtomicCounter(FfxUInt32 slice) {