Skip to content

DoF: avoid calling GetDimensions for LoDs in the shader #1256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ private enum SMAAStage

HDRenderPipeline m_HDInstance;

bool m_IsDoFHisotoryValid = false;

void FillEmptyExposureTexture()
{
var tex = new Texture2D(1, 1, TextureFormat.RGHalf, false, true);
Expand Down Expand Up @@ -615,6 +617,12 @@ void PoolSource(ref RTHandle src, RTHandle dst)
{
using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.DepthOfField)))
{
// If we switch DoF modes and the old one was not using TAA, make sure we invalidate the history
if (taaEnabled && m_IsDoFHisotoryValid != m_DepthOfField.physicallyBased)
{
camera.resetPostProcessingHistory = true;
}

var destination = m_Pool.Get(Vector2.one, m_ColorFormat);
if (!m_DepthOfField.physicallyBased)
DoDepthOfField(cmd, camera, source, destination, taaEnabled);
Expand All @@ -634,6 +642,8 @@ void PoolSource(ref RTHandle src, RTHandle dst)
PoolSource(ref source, taaDestination);
postDoFTAAEnabled = true;
}

m_IsDoFHisotoryValid = (m_DepthOfField.physicallyBased && taaEnabled);
}
}

Expand Down Expand Up @@ -2279,6 +2289,20 @@ void ReprojectCoCHistory(CommandBuffer cmd, HDCamera camera, bool useMips, ref R
fullresCoC = nextCoCTex;
}

static void GetMipMapDimensions(RTHandle texture, int lod, out int width, out int height)
{
width = texture.rt.width;
height = texture.rt.height;

for (int level = 0; level < lod; ++level)
{
// Note: When the texture/mip size is an odd number, the size of the next level is rounded down.
// That's why we cannot find the actual size by doing (size >> lod).
width /= 2;
height /= 2;
}
}

#endregion

#region Depth Of Field (Physically based)
Expand Down Expand Up @@ -2375,8 +2399,12 @@ void DoPhysicallyBasedDepthOfField(CommandBuffer cmd, HDCamera camera, RTHandle

kernel = cs.FindKernel("KMain");
float sampleCount = Mathf.Max(m_DepthOfField.nearSampleCount, m_DepthOfField.farSampleCount);
float mipLevel = Mathf.Ceil(Mathf.Log(cocLimit, 2));
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, mipLevel, 0.0f));

// We only have up to 6 mip levels
float mipLevel = Mathf.Min(6, Mathf.Ceil(Mathf.Log(cocLimit, 2)));
GetMipMapDimensions(fullresCoC, (int)mipLevel, out var mipMapWidth, out var mipMapHeight);
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params, new Vector4(sampleCount, cocLimit, 0.0f, 0.0f));
cmd.SetComputeVectorParam(cs, HDShaderIDs._Params2, new Vector4(mipLevel, mipMapWidth, mipMapHeight, 0.0f));
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputTexture, source);
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._InputCoCTexture, fullresCoC);
cmd.SetComputeTextureParam(cs, kernel, HDShaderIDs._OutputTexture, destination);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@

CBUFFER_START(cb0)
float4 _Params;
float4 _Params2;
CBUFFER_END

#define NumRings _Params.x
#define MaxCoCRadius _Params.y
#define MaxCoCMipLevel _Params.z
#define MaxCoCMipLevel _Params2.x
#define MaxCoCMipWidth _Params2.y
#define MaxCoCMipHeight _Params2.z

// Input textures
TEXTURE2D_X(_InputTexture);
Expand Down Expand Up @@ -86,20 +89,9 @@ float GetCoCMaxRadius(int2 positionSS)
#ifndef ADAPTIVE_RADIUS
return MaxCoCRadius;
#else
// We only have up to 6 mip levels
int lod = min(6, MaxCoCMipLevel);

// TODO FIXME - (Seb) I added this patch for metal as it was causing a
// Shader error in 'DoFGather': 'GetDimensions' : no matching 5 parameter intrinsic method;
// But overall I am even not this if this call work on Metal.
#if defined(SHADER_API_METAL)
uint3 size;
// Texture2D<float4>.GetDimensions(uint, out uint width, out uint height, out uint levels)
_InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z);
#else
uint4 size;
_InputCoCTexture.GetDimensions(lod, size.x, size.y, size.z, size.w);
#endif

int lod = MaxCoCMipLevel;
uint2 size = float2(MaxCoCMipWidth, MaxCoCMipHeight);

// Take RTHandleScale into account and odd texture dimension sizes (it's not enough to do a positionSS >> lod)
uint2 coords = positionSS * _ScreenSize.zw * size.xy * _RTHandleScale.xy;
Expand Down