Pass through view format as a type hint to texture display/sampling

* This is only applicable really on D3D11 where the underlying texture
  can be typeless, and a default interpretation as unorm/float won't
  necessarily how the texture is actually being used.
This commit is contained in:
baldurk
2016-06-27 11:56:31 +02:00
parent e160457abb
commit edbd1ce89b
26 changed files with 591 additions and 282 deletions
+16 -2
View File
@@ -34,13 +34,14 @@ namespace renderdocui.Code
public class BoundResource
{
public BoundResource()
{ Id = ResourceId.Null; HighestMip = -1; FirstSlice = -1; }
{ Id = ResourceId.Null; HighestMip = -1; FirstSlice = -1; typeHint = FormatComponentType.None; }
public BoundResource(ResourceId id)
{ Id = id; HighestMip = -1; FirstSlice = -1; }
{ Id = id; HighestMip = -1; FirstSlice = -1; typeHint = FormatComponentType.None; }
public ResourceId Id;
public int HighestMip;
public int FirstSlice;
public FormatComponentType typeHint;
};
public struct BoundVBuffer
@@ -907,6 +908,7 @@ namespace renderdocui.Code
val.Id = s.SRVs[i].Resource;
val.HighestMip = (int)s.SRVs[i].HighestMip;
val.FirstSlice = (int)s.SRVs[i].FirstArraySlice;
val.typeHint = s.SRVs[i].Format.compType;
ret.Add(key, new BoundResource[] { val });
}
@@ -923,6 +925,7 @@ namespace renderdocui.Code
val.Id = m_GL.Textures[i].Resource;
val.HighestMip = (int)m_GL.Textures[i].HighestMip;
val.FirstSlice = (int)m_GL.Textures[i].FirstSlice;
val.typeHint = FormatComponentType.None;
ret.Add(key, new BoundResource[] { val });
}
@@ -959,6 +962,7 @@ namespace renderdocui.Code
val[i].Id = bind.binds[i].res;
val[i].HighestMip = (int)bind.binds[i].baseMip;
val[i].FirstSlice = (int)bind.binds[i].baseLayer;
val[i].typeHint = bind.binds[i].viewfmt.compType;
}
ret.Add(key, val);
@@ -991,6 +995,7 @@ namespace renderdocui.Code
val.Id = m_D3D11.m_CS.UAVs[i].Resource;
val.HighestMip = (int)m_D3D11.m_CS.UAVs[i].HighestMip;
val.FirstSlice = (int)m_D3D11.m_CS.UAVs[i].FirstArraySlice;
val.typeHint = m_D3D11.m_CS.UAVs[i].Format.compType;
ret.Add(key, new BoundResource[] { val });
}
@@ -1005,6 +1010,7 @@ namespace renderdocui.Code
val.Id = m_D3D11.m_OM.UAVs[i].Resource;
val.HighestMip = (int)m_D3D11.m_OM.UAVs[i].HighestMip;
val.FirstSlice = (int)m_D3D11.m_OM.UAVs[i].FirstArraySlice;
val.typeHint = FormatComponentType.None;
ret.Add(key, new BoundResource[] { val });
}
@@ -1022,6 +1028,7 @@ namespace renderdocui.Code
val.Id = m_GL.Images[i].Resource;
val.HighestMip = (int)m_GL.Images[i].Level;
val.FirstSlice = (int)m_GL.Images[i].Layer;
val.typeHint = m_GL.Images[i].Format.compType;
ret.Add(key, new BoundResource[] { val });
}
@@ -1057,6 +1064,7 @@ namespace renderdocui.Code
val[i].Id = bind.binds[i].res;
val[i].HighestMip = (int)bind.binds[i].baseMip;
val[i].FirstSlice = (int)bind.binds[i].baseLayer;
val[i].typeHint = bind.binds[i].viewfmt.compType;
}
ret.Add(key, val);
@@ -1081,6 +1089,7 @@ namespace renderdocui.Code
ret.Id = m_D3D11.m_OM.DepthTarget.Resource;
ret.HighestMip = (int)m_D3D11.m_OM.DepthTarget.HighestMip;
ret.FirstSlice = (int)m_D3D11.m_OM.DepthTarget.FirstArraySlice;
ret.typeHint = m_D3D11.m_OM.DepthTarget.Format.compType;
return ret;
}
else if (IsLogGL)
@@ -1089,6 +1098,7 @@ namespace renderdocui.Code
ret.Id = m_GL.m_FB.m_DrawFBO.Depth.Obj;
ret.HighestMip = (int)m_GL.m_FB.m_DrawFBO.Depth.Mip;
ret.FirstSlice = (int)m_GL.m_FB.m_DrawFBO.Depth.Layer;
ret.typeHint = FormatComponentType.None;
return ret;
}
else if (IsLogVK)
@@ -1102,6 +1112,7 @@ namespace renderdocui.Code
ret.Id = fb.attachments[rp.depthstencilAttachment].img;
ret.HighestMip = (int)fb.attachments[rp.depthstencilAttachment].baseMip;
ret.FirstSlice = (int)fb.attachments[rp.depthstencilAttachment].baseLayer;
ret.typeHint = fb.attachments[rp.depthstencilAttachment].viewfmt.compType;
return ret;
}
@@ -1125,6 +1136,7 @@ namespace renderdocui.Code
ret[i].Id = m_D3D11.m_OM.RenderTargets[i].Resource;
ret[i].HighestMip = (int)m_D3D11.m_OM.RenderTargets[i].HighestMip;
ret[i].FirstSlice = (int)m_D3D11.m_OM.RenderTargets[i].FirstArraySlice;
ret[i].typeHint = m_D3D11.m_OM.RenderTargets[i].Format.compType;
}
return ret;
@@ -1143,6 +1155,7 @@ namespace renderdocui.Code
ret[i].Id = m_GL.m_FB.m_DrawFBO.Color[db].Obj;
ret[i].HighestMip = (int)m_GL.m_FB.m_DrawFBO.Color[db].Mip;
ret[i].FirstSlice = (int)m_GL.m_FB.m_DrawFBO.Color[db].Layer;
ret[i].typeHint = FormatComponentType.None;
}
}
@@ -1163,6 +1176,7 @@ namespace renderdocui.Code
ret[i].Id = fb.attachments[rp.colorAttachments[i]].img;
ret[i].HighestMip = (int)fb.attachments[rp.colorAttachments[i]].baseMip;
ret[i].FirstSlice = (int)fb.attachments[rp.colorAttachments[i]].baseLayer;
ret[i].typeHint = fb.attachments[rp.colorAttachments[i]].viewfmt.compType;
}
}
+20
View File
@@ -814,5 +814,25 @@ namespace renderdoc
return "Unknown";
}
public static string Str(this FormatComponentType compType)
{
switch (compType)
{
case FormatComponentType.None: return "Typeless";
case FormatComponentType.Float: return "Float";
case FormatComponentType.UNorm: return "UNorm";
case FormatComponentType.SNorm: return "SNorm";
case FormatComponentType.UInt: return "UInt";
case FormatComponentType.SInt: return "SInt";
case FormatComponentType.UScaled: return "UScaled";
case FormatComponentType.SScaled: return "SScaled";
case FormatComponentType.Depth: return "Depth";
case FormatComponentType.Double: return "Double";
default: break;
}
return "Unknown";
}
}
}
+3
View File
@@ -645,6 +645,7 @@ namespace renderdoc
public class TextureDisplay
{
public ResourceId texid = ResourceId.Null;
public FormatComponentType typeHint = FormatComponentType.None;
public float rangemin = 0.0f;
public float rangemax = 1.0f;
public float scale = 1.0f;
@@ -671,6 +672,8 @@ namespace renderdoc
{
public ResourceId id = ResourceId.Null;
public FormatComponentType typeHint = FormatComponentType.None;
public FileType destType = FileType.DDS;
public Int32 mip = -1;
+12 -12
View File
@@ -88,7 +88,7 @@ namespace renderdoc
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayOutput_ClearThumbnails(IntPtr real);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayOutput_AddThumbnail(IntPtr real, IntPtr wnd, ResourceId texID);
private static extern bool ReplayOutput_AddThumbnail(IntPtr real, IntPtr wnd, ResourceId texID, FormatComponentType typeHint);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayOutput_Display(IntPtr real);
@@ -130,9 +130,9 @@ namespace renderdoc
{
return ReplayOutput_ClearThumbnails(m_Real);
}
public bool AddThumbnail(IntPtr wnd, ResourceId texID)
public bool AddThumbnail(IntPtr wnd, ResourceId texID, FormatComponentType typeHint)
{
return ReplayOutput_AddThumbnail(m_Real, wnd, texID);
return ReplayOutput_AddThumbnail(m_Real, wnd, texID, typeHint);
}
public bool Display()
@@ -251,7 +251,7 @@ namespace renderdoc
private static extern bool ReplayRenderer_GetDebugMessages(IntPtr real, IntPtr outmsgs);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_PixelHistory(IntPtr real, ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, IntPtr history);
private static extern bool ReplayRenderer_PixelHistory(IntPtr real, ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, FormatComponentType typeHint, IntPtr history);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_DebugVertex(IntPtr real, UInt32 vertid, UInt32 instid, UInt32 idx, UInt32 instOffset, UInt32 vertOffset, IntPtr outtrace);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
@@ -272,9 +272,9 @@ namespace renderdoc
private static extern bool ReplayRenderer_GetPostVSData(IntPtr real, UInt32 instID, MeshDataStage stage, IntPtr outdata);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_GetMinMax(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, IntPtr outminval, IntPtr outmaxval);
private static extern bool ReplayRenderer_GetMinMax(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, IntPtr outminval, IntPtr outmaxval);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_GetHistogram(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, float minval, float maxval, bool[] channels, IntPtr outhistogram);
private static extern bool ReplayRenderer_GetHistogram(IntPtr real, ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, float minval, float maxval, bool[] channels, IntPtr outhistogram);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_GetBufferData(IntPtr real, ResourceId buff, UInt64 offset, UInt64 len, IntPtr outdata);
@@ -634,11 +634,11 @@ namespace renderdoc
return ret;
}
public PixelModification[] PixelHistory(ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx)
public PixelModification[] PixelHistory(ResourceId target, UInt32 x, UInt32 y, UInt32 slice, UInt32 mip, UInt32 sampleIdx, FormatComponentType typeHint)
{
IntPtr mem = CustomMarshal.Alloc(typeof(templated_array));
bool success = ReplayRenderer_PixelHistory(m_Real, target, x, y, slice, mip, sampleIdx, mem);
bool success = ReplayRenderer_PixelHistory(m_Real, target, x, y, slice, mip, sampleIdx, typeHint, mem);
PixelModification[] ret = null;
@@ -761,12 +761,12 @@ namespace renderdoc
return ret;
}
public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, out PixelValue minval, out PixelValue maxval)
public bool GetMinMax(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, out PixelValue minval, out PixelValue maxval)
{
IntPtr mem1 = CustomMarshal.Alloc(typeof(PixelValue));
IntPtr mem2 = CustomMarshal.Alloc(typeof(PixelValue));
bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, mem1, mem2);
bool success = ReplayRenderer_GetMinMax(m_Real, tex, sliceFace, mip, sample, typeHint, mem1, mem2);
if (success)
{
@@ -785,7 +785,7 @@ namespace renderdoc
return success;
}
public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, float minval, float maxval,
public bool GetHistogram(ResourceId tex, UInt32 sliceFace, UInt32 mip, UInt32 sample, FormatComponentType typeHint, float minval, float maxval,
bool Red, bool Green, bool Blue, bool Alpha,
out UInt32[] histogram)
{
@@ -793,7 +793,7 @@ namespace renderdoc
bool[] channels = new bool[] { Red, Green, Blue, Alpha };
bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, sample, minval, maxval, channels, mem);
bool success = ReplayRenderer_GetHistogram(m_Real, tex, sliceFace, mip, sample, typeHint, minval, maxval, channels, mem);
histogram = null;
+65 -17
View File
@@ -125,6 +125,18 @@ namespace renderdocui.Windows
return GetBoundResource(core, arrayEl).FirstSlice;
}
public FormatComponentType GetTypeHint(Core core)
{
var curDraw = core.CurDrawcall;
bool copy, compute;
GetDrawContext(core, out copy, out compute);
if (copy || compute)
return FormatComponentType.None;
return GetBoundResource(core, arrayEl).typeHint;
}
public ResourceId GetResourceId(Core core)
{
return GetBoundResource(core, arrayEl).Id;
@@ -374,12 +386,19 @@ namespace renderdocui.Windows
public class TexSettings
{
public TexSettings() { r = g = b = true; a = false; mip = 0; slice = 0; minrange = 0.0f; maxrange = 1.0f; }
public TexSettings()
{
r = g = b = true; a = false;
mip = 0; slice = 0;
minrange = 0.0f; maxrange = 1.0f;
typeHint = FormatComponentType.None;
}
public bool r, g, b, a;
public bool depth, stencil;
public int mip, slice;
public float minrange, maxrange;
public FormatComponentType typeHint;
}
private Dictionary<ResourceId, TexSettings> m_TextureSettings = new Dictionary<ResourceId, TexSettings>();
@@ -1048,6 +1067,8 @@ namespace renderdocui.Windows
m_TexDisplay.darkBackgroundColour = darkBack;
m_TexDisplay.lightBackgroundColour = lightBack;
m_TexDisplay.typeHint = FormatComponentType.None;
m_Core.Renderer.BeginInvoke(RT_UpdateAndDisplay);
}
@@ -1086,6 +1107,8 @@ namespace renderdocui.Windows
m_TexDisplay.darkBackgroundColour = darkBack;
m_TexDisplay.lightBackgroundColour = lightBack;
m_TexDisplay.typeHint = FormatComponentType.None;
PixelPicked = false;
statusLabel.Text = "";
@@ -1127,7 +1150,7 @@ namespace renderdocui.Windows
UI_UpdateChannels();
}
private void InitResourcePreview(ResourcePreview prev, ResourceId id, bool force, Following follow, string bindName, string slotName)
private void InitResourcePreview(ResourcePreview prev, ResourceId id, FormatComponentType typeHint, bool force, Following follow, string bindName, string slotName)
{
if (id != ResourceId.Null || force)
{
@@ -1157,7 +1180,7 @@ namespace renderdocui.Windows
IntPtr handle = prev.ThumbnailHandle;
m_Core.Renderer.BeginInvoke((ReplayRenderer rep) =>
{
m_Output.AddThumbnail(handle, id);
m_Output.AddThumbnail(handle, id, typeHint);
});
}
else if (buf != null)
@@ -1176,7 +1199,7 @@ namespace renderdocui.Windows
IntPtr handle = prev.ThumbnailHandle;
m_Core.Renderer.BeginInvoke((ReplayRenderer rep) =>
{
m_Output.AddThumbnail(handle, ResourceId.Null);
m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None);
});
}
else
@@ -1185,7 +1208,7 @@ namespace renderdocui.Windows
IntPtr handle = prev.ThumbnailHandle;
m_Core.Renderer.BeginInvoke((ReplayRenderer rep) =>
{
m_Output.AddThumbnail(handle, ResourceId.Null);
m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None);
});
}
@@ -1209,7 +1232,7 @@ namespace renderdocui.Windows
prev.Init("Unused", tex.width, tex.height, tex.depth, tex.mips);
m_Core.Renderer.BeginInvoke((ReplayRenderer rep) =>
{
m_Output.AddThumbnail(handle, ResourceId.Null);
m_Output.AddThumbnail(handle, ResourceId.Null, FormatComponentType.None);
});
}
else
@@ -1238,6 +1261,7 @@ namespace renderdocui.Windows
for (int arrayIdx = 0; arrayIdx < arrayLen; arrayIdx++)
{
ResourceId id = resArray != null ? resArray[arrayIdx].Id : ResourceId.Null;
FormatComponentType typeHint = resArray != null ? resArray[arrayIdx].typeHint : FormatComponentType.None;
bool used = key.used;
bool skip = false;
@@ -1294,7 +1318,7 @@ namespace renderdocui.Windows
prevIndex++;
InitResourcePreview(prev, show ? id : ResourceId.Null, show, follow, bindName, slotName);
InitResourcePreview(prev, show ? id : ResourceId.Null, typeHint, show, follow, bindName, slotName);
}
}
}
@@ -1334,7 +1358,7 @@ namespace renderdocui.Windows
string bindName = copy ? "Destination" : "";
string slotName = copy ? "DST" : String.Format("{0}{1}", m_Core.CurPipelineState.OutputAbbrev(), rt);
InitResourcePreview(prev, RTs[rt].Id, false, follow, bindName, slotName);
InitResourcePreview(prev, RTs[rt].Id, RTs[rt].typeHint, false, follow, bindName, slotName);
}
// depth
@@ -1350,7 +1374,7 @@ namespace renderdocui.Windows
Following follow = new Following(FollowType.OutputDepth, ShaderStageType.Pixel, 0, 0);
InitResourcePreview(prev, Depth.Id, false, follow, "", "DS");
InitResourcePreview(prev, Depth.Id, Depth.typeHint, false, follow, "", "DS");
}
ShaderStageType[] stages = new ShaderStageType[] {
@@ -1449,9 +1473,9 @@ namespace renderdocui.Windows
private PointF m_PrevSize = PointF.Empty;
private void UI_SetHistogramRange(FetchTexture tex)
private void UI_SetHistogramRange(FetchTexture tex, FormatComponentType typeHint)
{
if (tex != null && tex.format.compType == FormatComponentType.SNorm)
if (tex != null && (tex.format.compType == FormatComponentType.SNorm || typeHint == FormatComponentType.SNorm))
rangeHistogram.SetRange(-1.0f, 1.0f);
else
rangeHistogram.SetRange(0.0f, 1.0f);
@@ -1487,10 +1511,19 @@ namespace renderdocui.Windows
m_TextureSettings[m_TexDisplay.texid].minrange = rangeHistogram.BlackPoint;
m_TextureSettings[m_TexDisplay.texid].maxrange = rangeHistogram.WhitePoint;
m_TextureSettings[m_TexDisplay.texid].typeHint = m_Following.GetTypeHint(m_Core);
}
m_TexDisplay.texid = tex.ID;
// interpret the texture according to the currently following type.
m_TexDisplay.typeHint = m_Following.GetTypeHint(m_Core);
// if there is no such type or it isn't being followed, use the last seen interpretation
if (m_TexDisplay.typeHint == FormatComponentType.None)
m_TexDisplay.typeHint = m_TextureSettings[m_TexDisplay.texid].typeHint;
m_CurPixelValue = null;
m_CurRealValue = null;
@@ -1678,14 +1711,14 @@ namespace renderdocui.Windows
depthDisplay.Checked = true;
norangePaint = true;
UI_SetHistogramRange(tex);
UI_SetHistogramRange(tex, m_TexDisplay.typeHint);
norangePaint = false;
}
// reset the range if desired
if (m_Core.Config.TextureViewer_ResetRange)
{
UI_SetHistogramRange(tex);
UI_SetHistogramRange(tex, m_TexDisplay.typeHint);
}
}
@@ -1868,6 +1901,12 @@ namespace renderdocui.Windows
texStatusDim.Text += " " + current.mips + " mips";
texStatusDim.Text += " - " + current.format.ToString();
if (current.format.compType != m_TexDisplay.typeHint &&
m_TexDisplay.typeHint != FormatComponentType.None)
{
texStatusDim.Text += " Viewed as type " + m_TexDisplay.typeHint.Str();
}
}
private bool PixelPicked
@@ -3083,7 +3122,7 @@ namespace renderdocui.Windows
private void reset01_Click(object sender, EventArgs e)
{
UI_SetHistogramRange(CurrentTexture);
UI_SetHistogramRange(CurrentTexture, m_TexDisplay.typeHint);
autoFit.Checked = false;
@@ -3115,7 +3154,10 @@ namespace renderdocui.Windows
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
PixelValue min, max;
bool success = r.GetMinMax(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx, out min, out max);
bool success = r.GetMinMax(m_TexDisplay.texid,
m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx,
m_TexDisplay.typeHint,
out min, out max);
if (success)
{
@@ -3206,7 +3248,9 @@ namespace renderdocui.Windows
bool success = true;
uint[] histogram;
success = r.GetHistogram(m_TexDisplay.texid, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx,
success = r.GetHistogram(m_TexDisplay.texid,
m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx,
m_TexDisplay.typeHint,
rangeHistogram.RangeMin, rangeHistogram.RangeMax,
m_TexDisplay.Red,
m_TexDisplay.Green && fmt.compCount > 1,
@@ -3356,7 +3400,10 @@ namespace renderdocui.Windows
Thread.Sleep(100);
m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
{
history = r.PixelHistory(CurrentTexture.ID, (UInt32)x, (UInt32)y, m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx);
history = r.PixelHistory(CurrentTexture.ID,
(UInt32)x, (UInt32)y,
m_TexDisplay.sliceFace, m_TexDisplay.mip, m_TexDisplay.sampleIdx,
m_TexDisplay.typeHint);
this.BeginInvoke(new Action(() =>
{
@@ -3419,6 +3466,7 @@ namespace renderdocui.Windows
m_SaveDialog = new TextureSaveDialog(m_Core);
m_SaveDialog.saveData.id = m_TexDisplay.texid;
m_SaveDialog.saveData.typeHint = m_TexDisplay.typeHint;
m_SaveDialog.saveData.slice.sliceIndex = (int)m_TexDisplay.sliceFace;
m_SaveDialog.saveData.mip = (int)m_TexDisplay.mip;