Browse Source

Register aliasable UAV resources globally, before and after scheduling shader dispatches, so that all compute shaders can make use of them but without requiring a whole lot of additional resource management code.

mac-autoexp
Nico de Poel 3 years ago
parent
commit
cd414d75f1
  1. 4
      Assets/Scripts/Fsr2Context.cs
  2. 38
      Assets/Scripts/Fsr2Pipeline.cs

4
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)

38
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<Fsr2.Fsr2Constants>());
commandBuffer.SetComputeConstantBufferParam(ComputeShader, CbSpd, _spdConstants, 0, Marshal.SizeOf<Fsr2.SpdConstants>());
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);
}
}

Loading…
Cancel
Save