Skip to content
This repository has been archived by the owner on Nov 30, 2020. It is now read-only.

Commit

Permalink
Improved waveform performances on consoles
Browse files Browse the repository at this point in the history
Will need to rewrite this at some point, it uses quite a naive approach
  • Loading branch information
Chman committed Jul 11, 2017
1 parent adda4b3 commit e053c92
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 20 deletions.
16 changes: 11 additions & 5 deletions PostProcessing/Runtime/Monitors/WaveformMonitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ internal override void Render(PostProcessRenderContext context)
cmd.BeginSample("Waveform");

var parameters = new Vector4(
context.width / 2,
context.height / 2,
width,
height,
RuntimeUtilities.isLinearColorSpace ? 1 : 0,
0f
);
Expand All @@ -55,15 +55,21 @@ internal override void Render(PostProcessRenderContext context)
int kernel = compute.FindKernel("KWaveformClear");
cmd.SetComputeBufferParam(compute, kernel, "_WaveformBuffer", m_Data);
cmd.SetComputeVectorParam(compute, "_Params", parameters);
cmd.SetComputeVectorParam(compute, "_BufferParams", new Vector4(width, height, 0f, 0f));
cmd.DispatchCompute(compute, kernel, Mathf.CeilToInt(width / 16f), Mathf.CeilToInt(height / 16f), 1);

// For performance reasons, especially on consoles, we'll just downscale the source
// again to reduce VMEM stalls. Eventually the whole algorithm needs to be rewritten as
// it's currently pretty naive.
cmd.GetTemporaryRT(ShaderIDs.WaveformSource, width, height, 0, FilterMode.Bilinear, context.sourceFormat);
cmd.BlitFullscreenTriangle(ShaderIDs.HalfResFinalCopy, ShaderIDs.WaveformSource);

// Gather all pixels and fill in our waveform
kernel = compute.FindKernel("KWaveformGather");
cmd.SetComputeBufferParam(compute, kernel, "_WaveformBuffer", m_Data);
cmd.SetComputeTextureParam(compute, kernel, "_Source", ShaderIDs.HalfResFinalCopy);
cmd.SetComputeTextureParam(compute, kernel, "_Source", ShaderIDs.WaveformSource);
cmd.SetComputeVectorParam(compute, "_Params", parameters);
cmd.DispatchCompute(compute, kernel, Mathf.CeilToInt(context.width / 2f), Mathf.CeilToInt(context.width / 2f / 256f), 1);
cmd.DispatchCompute(compute, kernel, width, Mathf.CeilToInt(height / 256f), 1);
cmd.ReleaseTemporaryRT(ShaderIDs.WaveformSource);

// Generate the waveform texture
var sheet = context.propertySheets.Get(context.resources.shaders.waveform);
Expand Down
4 changes: 1 addition & 3 deletions PostProcessing/Runtime/PostProcessMonitors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,7 @@ internal void Render(PostProcessRenderContext context)

if (needHalfRes)
{
var format = RenderTextureFormat.ARGBHalf;
format = SystemInfo.SupportsRenderTextureFormat(format) ? format : RenderTextureFormat.ARGB32;
cmd.GetTemporaryRT(ShaderIDs.HalfResFinalCopy, context.width / 2, context.height / 2, 0, FilterMode.Bilinear, format);
cmd.GetTemporaryRT(ShaderIDs.HalfResFinalCopy, context.width / 2, context.height / 2, 0, FilterMode.Bilinear, context.sourceFormat);
cmd.Blit(context.destination, ShaderIDs.HalfResFinalCopy);
}

Expand Down
1 change: 1 addition & 0 deletions PostProcessing/Runtime/Utils/ShaderIDs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ static class ShaderIDs
internal static readonly int Interp = Shader.PropertyToID("_Interp");

internal static readonly int HalfResFinalCopy = Shader.PropertyToID("_HalfResFinalCopy");
internal static readonly int WaveformSource = Shader.PropertyToID("_WaveformSource");
internal static readonly int WaveformBuffer = Shader.PropertyToID("_WaveformBuffer");
internal static readonly int VectorscopeBuffer = Shader.PropertyToID("_VectorscopeBuffer");
}
Expand Down
20 changes: 9 additions & 11 deletions PostProcessing/Shaders/Debug/Waveform.compute
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,36 @@ SamplerState sampler_Source;

CBUFFER_START(Params)
float4 _Params; // x: source width, y: source height, z: linear, w: unused
float4 _BufferParams; // x: buffer width, y: buffer height, zw: unused
CBUFFER_END

#pragma kernel KWaveformGather
[numthreads(1, 256, 1)]
void KWaveformGather(uint2 dispatchThreadId : SV_DispatchThreadID, uint2 groupThreadId : SV_GroupThreadID)
void KWaveformGather(uint2 dispatchThreadId : SV_DispatchThreadID)
{
// Gather local group histogram
if (dispatchThreadId.x < uint(_Params.x) && dispatchThreadId.y < uint(_Params.y))
{
float2 coords = float2(dispatchThreadId) / _Params.xy;
float3 color = _Source.SampleLevel(sampler_Source, coords, 0).xyz;
float3 color = _Source[dispatchThreadId].rgb;
color = saturate(color);

// We want a gamma-corrected histogram (like Photoshop & all)
if (_Params.z > 0)
color = LinearToSRGB(color);

// Convert channel values to histogram bins
uint3 idx = (uint3)(round(color * (_BufferParams.y - 1)));
uint3 idx = (uint3)(round(color * (_Params.y - 1)));
idx += dispatchThreadId.x * _Params.y;

uint bufferX = uint(round(coords.x * (_BufferParams.x - 1)));
if (idx.x > 0u) InterlockedAdd(_WaveformBuffer[idx.x * uint(_BufferParams.x) + bufferX].x, 1u); // Red
if (idx.y > 0u) InterlockedAdd(_WaveformBuffer[idx.y * uint(_BufferParams.x) + bufferX].y, 1u); // Green
if (idx.z > 0u) InterlockedAdd(_WaveformBuffer[idx.z * uint(_BufferParams.x) + bufferX].z, 1u); // Blue
if (idx.x > 0u) InterlockedAdd(_WaveformBuffer[idx.x].x, 1u); // Red
if (idx.y > 0u) InterlockedAdd(_WaveformBuffer[idx.y].y, 1u); // Green
if (idx.z > 0u) InterlockedAdd(_WaveformBuffer[idx.z].z, 1u); // Blue
}
}

#pragma kernel KWaveformClear
[numthreads(16, 16, 1)]
void KWaveformClear(uint2 dispatchThreadId : SV_DispatchThreadID)
{
if (dispatchThreadId.x < uint(_BufferParams.x) && dispatchThreadId.y < uint(_BufferParams.y))
_WaveformBuffer[dispatchThreadId.y * uint(_BufferParams.x) + dispatchThreadId.x] = uint4(0u, 0u, 0u, 0u);
if (dispatchThreadId.x < uint(_Params.x) && dispatchThreadId.y < uint(_Params.y))
_WaveformBuffer[dispatchThreadId.y * uint(_Params.x) + dispatchThreadId.x] = uint4(0u, 0u, 0u, 0u);
}
2 changes: 1 addition & 1 deletion PostProcessing/Shaders/Debug/Waveform.shader
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Shader "Hidden/PostProcessing/Debug/Waveform"
float3 color = float3(0.0, 0.0, 0.0);

uint2 uvI = i.vertex.xy;
float3 w = _WaveformBuffer[uvI.y * _Params.x + uvI.x];
float3 w = _WaveformBuffer[uvI.x * _Params.y + uvI.y].xyz;

color += red * w.r;
color += green * w.g;
Expand Down

0 comments on commit e053c92

Please sign in to comment.