diff --git a/Assets/Scripts/Fsr2Context.cs b/Assets/Scripts/Fsr2Context.cs index de549aa..d034653 100644 --- a/Assets/Scripts/Fsr2Context.cs +++ b/Assets/Scripts/Fsr2Context.cs @@ -184,6 +184,8 @@ namespace FidelityFX _fsr2ConstantsBuffer.SetData(_fsr2ConstantsArray); _spdConstantsBuffer.SetData(_spdConstantsArray); + Fsr2Pipeline.RegisterResources(_commandBuffer, dispatchParams); + // Compute luminance pyramid _computeLuminancePyramidPipeline.ScheduleDispatch(_commandBuffer, dispatchParams, dispatchThreadGroupCount.x, dispatchThreadGroupCount.y); @@ -224,7 +226,7 @@ namespace FidelityFX Graphics.ExecuteCommandBuffer(_commandBuffer); - // TODO Unregister resources: release temp RT's + Fsr2Pipeline.UnregisterResources(_commandBuffer); } private void SetupConstants(Fsr2.DispatchDescription dispatchParams, bool resetAccumulation) diff --git a/Assets/Scripts/Fsr2Pipeline.cs b/Assets/Scripts/Fsr2Pipeline.cs index 20c54db..8c1818b 100644 --- a/Assets/Scripts/Fsr2Pipeline.cs +++ b/Assets/Scripts/Fsr2Pipeline.cs @@ -45,8 +45,29 @@ namespace FidelityFX { UnloadComputeShader(); } - + public abstract void ScheduleDispatch(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams, int dispatchX, int dispatchY); + + public static void RegisterResources(CommandBuffer commandBuffer, Fsr2.DispatchDescription dispatchParams) + { + // Set up shared aliasable resources, i.e. temporary render textures + // These do not need to persist between frames, but they do need to be available between compute stages + + // Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE + commandBuffer.GetTemporaryRT(UavSpdAtomicCount, 1, 1, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true); + + // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE, has mipmap chain + commandBuffer.GetTemporaryRT(UavExposureMipLumaChange, dispatchParams.RenderSize.x >> 4, dispatchParams.RenderSize.y >> 4, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); + commandBuffer.GetTemporaryRT(UavExposureMip5, dispatchParams.RenderSize.x >> 5, dispatchParams.RenderSize.y >> 5, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); + } + + public static void UnregisterResources(CommandBuffer commandBuffer) + { + // Release all of the aliasable resources used this frame + commandBuffer.ReleaseTemporaryRT(UavSpdAtomicCount); + commandBuffer.ReleaseTemporaryRT(UavExposureMipLumaChange); + commandBuffer.ReleaseTemporaryRT(UavExposureMip5); + } protected void LoadComputeShader(string name, Fsr2.InitializationFlags flags) { @@ -109,24 +130,11 @@ namespace FidelityFX // - Shouldn't we use a ComputeBuffer for resources that are one-dimensional and clearly not image data? e.g. SPD atomic counter & Lanczos LUT data commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, SrvInputColor, dispatchParams.Input); - // Resource FSR2_SpdAtomicCounter: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R32_UINT, FFX_RESOURCE_FLAGS_ALIASABLE - commandBuffer.GetTemporaryRT(UavSpdAtomicCount, 1, 1, 0, FilterMode.Point, GraphicsFormat.R32_UInt, 1, true); // FSR2_BIND_UAV_SPD_GLOBAL_ATOMIC - // Resource FSR2_ExposureMips: FFX_RESOURCE_USAGE_UAV, FFX_SURFACE_FORMAT_R16_FLOAT, FFX_RESOURCE_FLAGS_ALIASABLE, mipCount = 0 - // See `scheduleDispatch` for the song and dance to bind UAV mip levels to each luminance mipmap... and this shader specifically wants mip levels 4 and 5 - // Looks like we can just bind two separate resources here, shouldn't be necessary to bother with mipmapping nonsense. Be sure to get the right dimensions though. - commandBuffer.GetTemporaryRT(UavExposureMipLumaChange, dispatchParams.RenderSize.x >> 4, dispatchParams.RenderSize.y >> 4, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); // FSR2_BIND_UAV_EXPOSURE_MIP_LUMA_CHANGE - commandBuffer.GetTemporaryRT(UavExposureMip5, dispatchParams.RenderSize.x >> 5, dispatchParams.RenderSize.y >> 5, 0, FilterMode.Point, GraphicsFormat.R16_SFloat, 1, true); // FSR2_BIND_UAV_EXPOSURE_MIP_5 - commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, _autoExposure); // FSR2_BIND_UAV_AUTO_EXPOSURE + commandBuffer.SetComputeTextureParam(ComputeShader, KernelIndex, UavAutoExposure, _autoExposure); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbFsr2, Constants, 0, Marshal.SizeOf()); commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf()); commandBuffer.DispatchCompute(ComputeShader, KernelIndex, dispatchX, dispatchY, 1); - - // NOTE: since these temp RTs are not bound to a specific shader or kernel, we can set them globally one time and release them after dispatch. - // That way we can share aliasable resources between shaders without any complicated management. - commandBuffer.ReleaseTemporaryRT(UavSpdAtomicCount); - commandBuffer.ReleaseTemporaryRT(UavExposureMipLumaChange); - commandBuffer.ReleaseTemporaryRT(UavExposureMip5); } }