From 09f8dc93dc240fd63b92cd2774833c254d8e1349 Mon Sep 17 00:00:00 2001 From: baldurk Date: Thu, 30 Oct 2014 22:53:10 +0000 Subject: [PATCH] Better handling of NaN/inf in range histogram * This is the proper fix for 87bcde1c which is also more explicit about what is going wrong. Thanks to the anonymous user who mentioned that they clicked auto-fit before hitting the range histogram crash, which got me on the right path to track down the exception! --- renderdoc/driver/d3d11/d3d11_debug.cpp | 5 +++ renderdocui/Controls/RangeHistogram.cs | 54 ++++++++++++++------------ 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/renderdoc/driver/d3d11/d3d11_debug.cpp b/renderdoc/driver/d3d11/d3d11_debug.cpp index 58488adf7..6e820d63e 100644 --- a/renderdoc/driver/d3d11/d3d11_debug.cpp +++ b/renderdoc/driver/d3d11/d3d11_debug.cpp @@ -3310,6 +3310,11 @@ bool D3D11DebugManager::RenderTexture(TextureDisplay cfg, bool blendAlpha) pixelData.RangeMinimum = cfg.rangemin; pixelData.InverseRangeSize = 1.0f/(cfg.rangemax-cfg.rangemin); + if(_isnan(pixelData.InverseRangeSize) || !_finite(pixelData.InverseRangeSize)) + { + pixelData.InverseRangeSize = FLT_MAX; + } + pixelData.WireframeColour.x = cfg.HDRMul; pixelData.RawOutput = cfg.rawoutput ? 1 : 0; diff --git a/renderdocui/Controls/RangeHistogram.cs b/renderdocui/Controls/RangeHistogram.cs index 34a5663fb..86b274b1e 100644 --- a/renderdocui/Controls/RangeHistogram.cs +++ b/renderdocui/Controls/RangeHistogram.cs @@ -101,6 +101,22 @@ namespace renderdocui.Controls OnRangeUpdated(new RangeHistogramEventArgs(BlackPoint, WhitePoint)); } + public bool ValidRange + { + get + { + if (float.IsInfinity(m_WhitePoint) || float.IsNaN(m_WhitePoint) || + float.IsInfinity(m_BlackPoint) || float.IsNaN(m_BlackPoint) || + float.IsInfinity(m_RangeMax) || float.IsNaN(m_RangeMax) || + float.IsInfinity(m_RangeMin) || float.IsNaN(m_RangeMin)) + { + return false; + } + + return true; + } + } + [Browsable(false)] public uint[] HistogramData { @@ -235,6 +251,7 @@ namespace renderdocui.Controls { get { + if (!ValidRange) return 0.0f; return GetDelta(BlackPoint); } set @@ -246,6 +263,7 @@ namespace renderdocui.Controls { get { + if (!ValidRange) return 1.0f; return GetDelta(WhitePoint); } set @@ -290,7 +308,7 @@ namespace renderdocui.Controls // grab when you clicked. private void RangeHistogram_MouseDown(object sender, MouseEventArgs e) { - if(e.Button != MouseButtons.Left) + if(e.Button != MouseButtons.Left || !ValidRange) return; Rectangle rect = this.ClientRectangle; @@ -354,7 +372,7 @@ namespace renderdocui.Controls private void RangeHistogram_MouseMove(object sender, MouseEventArgs e) { - if (e.Button == MouseButtons.Left && (e.X != m_mousePrev.X || e.Y != m_mousePrev.Y)) + if (ValidRange && e.Button == MouseButtons.Left && (e.X != m_mousePrev.X || e.Y != m_mousePrev.Y)) { if (m_DragMode == DraggingMode.WHITE) { @@ -411,7 +429,7 @@ namespace renderdocui.Controls rect.Inflate(-m_Border, -m_Border); - e.Graphics.FillRectangle(Brushes.DarkGray, rect); + e.Graphics.FillRectangle(ValidRange ? Brushes.DarkGray : Brushes.DarkRed, rect); int whiteX = (int)(m_WhiteDelta * rect.Width); int blackX = (int)(m_BlackDelta * rect.Width); @@ -422,6 +440,9 @@ namespace renderdocui.Controls e.Graphics.FillRectangle(Brushes.White, whitePoint); e.Graphics.FillRectangle(Brushes.Black, blackPoint); + if (!ValidRange) + return; + if (HistogramData != null) { float minx = GetDelta(m_HistogramMin); @@ -459,24 +480,16 @@ namespace renderdocui.Controls } } - Point[] blackTriangle = { new Point(blackPoint.Right, m_MarkerSize*2), - new Point(blackPoint.Right + m_MarkerSize, 0), - new Point(blackPoint.Right - m_MarkerSize, 0) }; + Point[] blackTriangle = { new Point(blackPoint.Right, m_MarkerSize*2), + new Point(blackPoint.Right+m_MarkerSize, 0), + new Point(blackPoint.Right-m_MarkerSize, 0) }; + + e.Graphics.FillPolygon(Brushes.DarkGray, blackTriangle); Point[] whiteTriangle = { new Point(whitePoint.Left, whitePoint.Bottom-m_MarkerSize*2+m_Margin), new Point(whitePoint.Left+m_MarkerSize, whitePoint.Bottom+m_Margin), new Point(whitePoint.Left-m_MarkerSize, whitePoint.Bottom+m_Margin) }; - for (int i = 0; i < 3; i++) - { - blackTriangle[i].X = Helpers.Clamp(blackTriangle[i].X, (int)e.Graphics.ClipBounds.Left-1, (int)e.Graphics.ClipBounds.Right+1); - blackTriangle[i].Y = Helpers.Clamp(blackTriangle[i].Y, (int)e.Graphics.ClipBounds.Top-1, (int)e.Graphics.ClipBounds.Bottom+1); - - whiteTriangle[i].X = Helpers.Clamp(whiteTriangle[i].X, (int)e.Graphics.ClipBounds.Left-1, (int)e.Graphics.ClipBounds.Right+1); - whiteTriangle[i].Y = Helpers.Clamp(whiteTriangle[i].Y, (int)e.Graphics.ClipBounds.Top-1, (int)e.Graphics.ClipBounds.Bottom+1); - } - - e.Graphics.FillPolygon(Brushes.DarkGray, blackTriangle); e.Graphics.FillPolygon(Brushes.DarkGray, whiteTriangle); blackTriangle[0].Y -= 2; @@ -493,15 +506,6 @@ namespace renderdocui.Controls whiteTriangle[1].X -= 2; whiteTriangle[2].X += 2; - for (int i = 0; i < 3; i++) - { - blackTriangle[i].X = Helpers.Clamp(blackTriangle[i].X, (int)e.Graphics.ClipBounds.Left - 1, (int)e.Graphics.ClipBounds.Right + 1); - blackTriangle[i].Y = Helpers.Clamp(blackTriangle[i].Y, (int)e.Graphics.ClipBounds.Top - 1, (int)e.Graphics.ClipBounds.Bottom + 1); - - whiteTriangle[i].X = Helpers.Clamp(whiteTriangle[i].X, (int)e.Graphics.ClipBounds.Left - 1, (int)e.Graphics.ClipBounds.Right + 1); - whiteTriangle[i].Y = Helpers.Clamp(whiteTriangle[i].Y, (int)e.Graphics.ClipBounds.Top - 1, (int)e.Graphics.ClipBounds.Bottom + 1); - } - e.Graphics.FillPolygon(Brushes.Black, blackTriangle); e.Graphics.FillPolygon(Brushes.White, whiteTriangle); }