Add externally visible API to query for pixel history

This commit is contained in:
baldurk
2014-07-08 09:19:40 +01:00
parent 25c4771589
commit 4e51aab9e5
15 changed files with 209 additions and 3 deletions
+46
View File
@@ -524,6 +524,24 @@ void Serialiser::Serialise(const char *name, PostVSMeshData &el)
Serialise("", el.buf);
}
template<>
void Serialiser::Serialise(const char *name, PixelModification &el)
{
Serialise("", el.eventID);
Serialise<4>("", el.preMod.value_u);
Serialise<4>("", el.shaderOut.value_u);
Serialise<4>("", el.postMod.value_u);
Serialise("", el.backfaceCulled);
Serialise("", el.depthClipped);
Serialise("", el.viewClipped);
Serialise("", el.scissorClipped);
Serialise("", el.shaderDiscared);
Serialise("", el.depthTestFailed);
Serialise("", el.stencilTestFailed);
}
template<>
void Serialiser::Serialise(const char *name, ShaderDebugState &el)
{
@@ -751,6 +769,9 @@ bool ProxySerialiser::Tick()
case eCommand_RenderOverlay:
RenderOverlay(ResourceId(), eTexOverlay_None, 0, 0);
break;
case eCommand_PixelHistory:
PixelHistory(0, vector<uint32_t>(), ResourceId(), 0, 0);
break;
case eCommand_DebugVertex:
DebugVertex(0, 0, 0, 0, 0, 0, 0);
break;
@@ -1439,6 +1460,31 @@ void ProxySerialiser::RemoveReplacement(ResourceId id)
}
}
vector<PixelModification> ProxySerialiser::PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y)
{
vector<PixelModification> ret;
m_ToReplaySerialiser->Serialise("", frameID);
m_ToReplaySerialiser->Serialise("", events);
m_ToReplaySerialiser->Serialise("", target);
m_ToReplaySerialiser->Serialise("", x);
m_ToReplaySerialiser->Serialise("", y);
if(m_ReplayHost)
{
ret = m_Remote->PixelHistory(frameID, events, target, x, y);
}
else
{
if(!SendReplayCommand(eCommand_PixelHistory))
return ret;
}
m_FromReplaySerialiser->Serialise("", ret);
return ret;
}
ShaderDebugTrace ProxySerialiser::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset)
{
ShaderDebugTrace ret;
+3
View File
@@ -73,6 +73,8 @@ enum CommandPacketType
eCommand_RenderOverlay,
eCommand_GetAPIProperties,
eCommand_PixelHistory,
};
// This class implements IReplayDriver and StackResolver. On the local machine where the UI
@@ -308,6 +310,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
void FreeTargetResource(ResourceId id);
vector<PixelModification> PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y);
ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset);
ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y);
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
+6
View File
@@ -2705,3 +2705,9 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver
return m_OverlayResourceId;
}
vector<PixelModification> D3D11DebugManager::PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y)
{
RDCUNIMPLEMENTED("D3D11DebugManager::PixelHistory");
return vector<PixelModification>();
}
+1
View File
@@ -152,6 +152,7 @@ class D3D11DebugManager
void RenderHighlightBox(float w, float h, float scale);
vector<PixelModification> PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y);
ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset);
ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y);
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
+5
View File
@@ -1276,6 +1276,11 @@ void D3D11Replay::FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vec
return;
}
vector<PixelModification> D3D11Replay::PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y)
{
return m_pDevice->GetDebugManager()->PixelHistory(frameID, events, target, x, y);
}
ShaderDebugTrace D3D11Replay::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset)
{
return m_pDevice->GetDebugManager()->DebugVertex(frameID, eventID, vertid, instid, idx, instOffset, vertOffset);
+2 -1
View File
@@ -110,7 +110,8 @@ class D3D11Replay : public IReplayDriver
void RenderHighlightBox(float w, float h, float scale);
void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data);
vector<PixelModification> PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y);
ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset);
ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y);
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
+6
View File
@@ -1313,6 +1313,12 @@ void GLReplay::BuildCustomShader(string source, string entry, const uint32_t com
RDCUNIMPLEMENTED("BuildCustomShader");
}
vector<PixelModification> GLReplay::PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y)
{
RDCUNIMPLEMENTED("GLReplay::PixelHistory");
return vector<PixelModification>();
}
ShaderDebugTrace GLReplay::DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset)
{
RDCUNIMPLEMENTED("DebugVertex");
+2 -1
View File
@@ -110,7 +110,8 @@ class GLReplay : public IReplayDriver
void RenderHighlightBox(float w, float h, float scale);
void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data);
vector<PixelModification> PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y);
ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset);
ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y);
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
+17
View File
@@ -202,6 +202,23 @@ struct PixelValue
};
};
struct PixelModification
{
uint32_t eventID;
PixelValue preMod;
PixelValue shaderOut;
PixelValue postMod;
bool32 backfaceCulled;
bool32 depthClipped;
bool32 viewClipped;
bool32 scissorClipped;
bool32 shaderDiscarded;
bool32 depthTestFailed;
bool32 stencilTestFailed;
};
struct PostVSMeshData
{
rdctype::array<byte> buf;
+1
View File
@@ -123,6 +123,7 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetBuffers(ReplayRende
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRenderer *rend, uint64_t *callstack, uint32_t callstackLen, rdctype::array<rdctype::wstr> *trace);
extern "C" RENDERDOC_API ShaderReflection* RENDERDOC_CC ReplayRenderer_GetShaderDetails(ReplayRenderer *rend, ResourceId shader);
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_PixelHistory(ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, rdctype::array<PixelModification> *history);
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_VSGetDebugStates(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace);
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_PSGetDebugStates(ReplayRenderer *rend, uint32_t x, uint32_t y, ShaderDebugTrace *trace);
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_CSGetDebugStates(ReplayRenderer *rend, uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace);
+1
View File
@@ -93,6 +93,7 @@ class IRemoteDriver
virtual void FillCBufferVariables(ResourceId shader, uint32_t cbufSlot, vector<ShaderVariable> &outvars, const vector<byte> &data) = 0;
virtual vector<PixelModification> PixelHistory(uint32_t frameID, vector<uint32_t> events, ResourceId target, uint32_t x, uint32_t y) = 0;
virtual ShaderDebugTrace DebugVertex(uint32_t frameID, uint32_t eventID, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset) = 0;
virtual ShaderDebugTrace DebugPixel(uint32_t frameID, uint32_t eventID, uint32_t x, uint32_t y) = 0;
virtual ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]) = 0;
+78
View File
@@ -326,6 +326,82 @@ bool ReplayRenderer::SaveTexture(ResourceId tex, uint32_t saveMip, const wchar_t
return m_pDevice->SaveTexture(m_pDevice->GetLiveID(tex), saveMip, path);
}
bool ReplayRenderer::PixelHistory(ResourceId target, uint32_t x, uint32_t y, rdctype::array<PixelModification> *history)
{
bool outofbounds = false;
for(size_t t=0; t < m_Textures.size(); t++)
{
if(m_Textures[t].ID == target)
{
if(x >= m_Textures[t].width || y >= m_Textures[t].height)
{
RDCDEBUG("PixelHistory out of bounds on %llx (%u,%u) vs (%u,%u)", target, x, y, m_Textures[t].width, m_Textures[t].height);
history->count = 0;
history->elems = NULL;
return false;
}
break;
}
}
auto usage = m_pDevice->GetUsage(m_pDevice->GetLiveID(target));
vector<uint32_t> events;
for(size_t i=0; i < usage.size(); i++)
{
if(usage[i].eventID > m_EventID)
continue;
switch(usage[i].usage)
{
case eUsage_IA_VB:
case eUsage_IA_IB:
case eUsage_VS_CB:
case eUsage_HS_CB:
case eUsage_DS_CB:
case eUsage_GS_CB:
case eUsage_PS_CB:
case eUsage_CS_CB:
case eUsage_VS_SRV:
case eUsage_HS_SRV:
case eUsage_DS_SRV:
case eUsage_GS_SRV:
case eUsage_PS_SRV:
case eUsage_CS_SRV:
// read-only, not a valid pixel history event
continue;
case eUsage_SO:
case eUsage_CS_UAV:
case eUsage_PS_UAV:
case eUsage_OM_RTV:
case eUsage_OM_DSV:
case eUsage_Clear:
// writing - include in pixel history events
break;
}
events.push_back(usage[i].eventID);
}
if(events.empty())
{
RDCDEBUG("Target %llx not written to before %u", target, m_EventID);
history->count = 0;
history->elems = NULL;
return false;
}
*history = m_pDevice->PixelHistory(m_FrameID, events, m_pDevice->GetLiveID(target), x, y);
SetFrameEvent(m_FrameID, m_EventID, true);
return true;
}
bool ReplayRenderer::VSGetDebugStates(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace)
{
if(trace == NULL) return false;
@@ -694,6 +770,8 @@ extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_GetResolve(ReplayRende
extern "C" RENDERDOC_API ShaderReflection* RENDERDOC_CC ReplayRenderer_GetShaderDetails(ReplayRenderer *rend, ResourceId shader)
{ return rend->GetShaderDetails(shader); }
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_PixelHistory(ReplayRenderer *rend, ResourceId target, uint32_t x, uint32_t y, rdctype::array<PixelModification> *history)
{ return rend->PixelHistory(target, x, y, history); }
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_VSGetDebugStates(ReplayRenderer *rend, uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace)
{ return rend->VSGetDebugStates(vertid, instid, idx, instOffset, vertOffset, trace); }
extern "C" RENDERDOC_API bool RENDERDOC_CC ReplayRenderer_PSGetDebugStates(ReplayRenderer *rend, uint32_t x, uint32_t y, ShaderDebugTrace *trace)
+1
View File
@@ -158,6 +158,7 @@ struct ReplayRenderer
bool GetResolve(uint64_t *callstack, uint32_t callstackLen, rdctype::array<rdctype::wstr> *trace);
ShaderReflection *GetShaderDetails(ResourceId shader);
bool PixelHistory(ResourceId target, uint32_t x, uint32_t y, rdctype::array<PixelModification> *history);
bool VSGetDebugStates(uint32_t vertid, uint32_t instid, uint32_t idx, uint32_t instOffset, uint32_t vertOffset, ShaderDebugTrace *trace);
bool PSGetDebugStates(uint32_t x, uint32_t y, ShaderDebugTrace *trace);
bool CSGetDebugStates(uint32_t groupid[3], uint32_t threadid[3], ShaderDebugTrace *trace);
+21
View File
@@ -457,6 +457,27 @@ namespace renderdoc
public ValueUnion value;
};
[StructLayout(LayoutKind.Sequential)]
public class PixelModification
{
public UInt32 eventID;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public PixelValue preMod;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public PixelValue shaderOut;
[CustomMarshalAs(CustomUnmanagedType.CustomClass)]
public PixelValue postMod;
public bool backfaceCulled;
public bool depthClipped;
public bool viewClipped;
public bool scissorClipped;
public bool shaderDiscarded;
public bool depthTestFailed;
public bool stencilTestFailed;
};
[StructLayout(LayoutKind.Sequential)]
public class PostVSMeshData
{
+19 -1
View File
@@ -209,7 +209,9 @@ namespace renderdoc
private static extern bool ReplayRenderer_GetResolve(IntPtr real, UInt64[] callstack, UInt32 callstackLen, IntPtr outtrace);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr ReplayRenderer_GetShaderDetails(IntPtr real, ResourceId shader);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_PixelHistory(IntPtr real, ResourceId target, UInt32 x, UInt32 y, IntPtr history);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
private static extern bool ReplayRenderer_VSGetDebugStates(IntPtr real, UInt32 vertid, UInt32 instid, UInt32 idx, UInt32 instOffset, UInt32 vertOffset, IntPtr outtrace);
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
@@ -488,6 +490,22 @@ namespace renderdoc
return ret;
}
public PixelModification[] PixelHistory(ResourceId target, UInt32 x, UInt32 y)
{
IntPtr mem = CustomMarshal.Alloc(typeof(templated_array));
bool success = ReplayRenderer_PixelHistory(m_Real, target, x, y, mem);
PixelModification[] ret = null;
if (success)
ret = (PixelModification[])CustomMarshal.GetTemplatedArray(mem, typeof(PixelModification), true);
CustomMarshal.Free(mem);
return ret;
}
public ShaderDebugTrace VSGetDebugStates(UInt32 vertid, UInt32 instid, UInt32 idx, UInt32 instOffset, UInt32 vertOffset)
{
IntPtr mem = CustomMarshal.Alloc(typeof(ShaderDebugTrace));