Add quad overdraw mode. Thanks Stephen Hill (@self_shadow)!

* http://blog.selfshadow.com/2012/11/12/counting-quads/
* Quad Overdraw based on ScenePS4 from the revised implementation. The
  colours are new, up to 20 levels. Picking pixels shows the overdraw level
* Available per-pass and per-drawcall, a pass defined the same way as in
  the mesh view, drawcalls since last clear or RT change.
* List of events now passed through to RenderOverlay the same as RenderMesh
This commit is contained in:
baldurk
2014-08-17 15:28:51 +01:00
parent 8a5150297f
commit 55e0178ec9
19 changed files with 384 additions and 89 deletions
+7 -4
View File
@@ -784,7 +784,7 @@ bool ProxySerialiser::Tick()
RemoveReplacement(ResourceId());
break;
case eCommand_RenderOverlay:
RenderOverlay(ResourceId(), eTexOverlay_None, 0, 0);
RenderOverlay(ResourceId(), eTexOverlay_None, 0, 0, vector<uint32_t>());
break;
case eCommand_PixelHistory:
PixelHistory(0, vector<uint32_t>(), ResourceId(), 0, 0);
@@ -1270,18 +1270,21 @@ PostVSMeshData ProxySerialiser::GetPostVSBuffers(uint32_t frameID, uint32_t even
return ret;
}
ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID)
ResourceId ProxySerialiser::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents)
{
ResourceId ret;
vector<uint32_t> events = passEvents;
m_ToReplaySerialiser->Serialise("", texid);
m_ToReplaySerialiser->Serialise("", overlay);
m_ToReplaySerialiser->Serialise("", frameID);
m_ToReplaySerialiser->Serialise("", eventID);
m_ToReplaySerialiser->Serialise("", events);
if(m_ReplayHost)
{
ret = m_Remote->RenderOverlay(texid, overlay, frameID, eventID);
ret = m_Remote->RenderOverlay(texid, overlay, frameID, eventID, events);
}
else
{
+2 -2
View File
@@ -224,7 +224,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
}
}
void RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg)
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
{
if(m_Proxy)
m_Proxy->RenderCheckerboard(Vec3f(0.7f, 0.3f, 0.3f), Vec3f(0.3f, 0.3f, 0.7f));
@@ -298,7 +298,7 @@ class ProxySerialiser : public IReplayDriver, Callstack::StackResolver
void InitPostVSBuffers(uint32_t frameID, uint32_t eventID);
PostVSMeshData GetPostVSBuffers(uint32_t frameID, uint32_t eventID, MeshDataStage stage);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
ShaderReflection *GetShader(ResourceId id);
+56
View File
@@ -332,3 +332,59 @@ float4 RENDERDOC_CheckerboardPS(float4 IN : SV_Position) : SV_Target0
return float4(sqrt(Channels.rgb), 1);
}
////////////////////////////////////////////////////////////////////////////////////////////
// Below shaders courtesy of Stephen Hill (@self_shadow)
//
// http://blog.selfshadow.com/2012/11/12/counting-quads/
// https://github.com/selfshadow/demos/blob/master/QuadShading/QuadShading.fx
////////////////////////////////////////////////////////////////////////////////////////////
RWTexture2DArray<uint> overdrawUAV : register(u0);
Texture2DArray<uint> overdrawSRV : register(t0);
cbuffer overdrawRampCBuf : register(b0)
{
const float4 overdrawRampColours[21];
};
[earlydepthstencil]
void RENDERDOC_QuadOverdrawPS(float4 vpos : SV_Position, uint c0 : SV_Coverage)
{
// Obtain coverage for all pixels in the quad, via 'message passing'*.
// (* For more details, see:
// "Shader Amortization using Pixel Quad Message Passing", Eric Penner, GPU Pro 2.)
uint2 p = uint2(vpos.xy) & 1;
int2 sign = p ? -1 : 1;
uint c1 = c0 + sign.x*ddx_fine(c0);
uint c2 = c0 + sign.y*ddy_fine(c0);
uint c3 = c2 + sign.x*ddx_fine(c2);
// Count the live pixels, minus 1 (zero indexing)
uint pixelCount = c0 + c1 + c2 + c3 - 1;
uint3 quad = uint3(vpos.xy*0.5, pixelCount);
InterlockedAdd(overdrawUAV[quad], 1);
}
float4 ToColour(uint v)
{
return overdrawRampColours[min(v, 20)];
}
float4 RENDERDOC_QOResolvePS(float4 vpos : SV_POSITION) : SV_Target0
{
uint2 quad = vpos.xy*0.5;
uint overdraw = 0;
for(int i = 0; i < 4; i++)
overdraw += overdrawSRV[uint3(quad, i)]/(i + 1);
return ToColour(overdraw);
}
////////////////////////////////////////////////////////////////////////////////////////////
// Above shaders courtesy of Stephen Hill (@self_shadow)
//
// http://blog.selfshadow.com/2012/11/12/counting-quads/
// https://github.com/selfshadow/demos/blob/master/QuadShading/QuadShading.fx
////////////////////////////////////////////////////////////////////////////////////////////
+166 -1
View File
@@ -2171,7 +2171,7 @@ void D3D11DebugManager::CreateCustomShaderTex(uint32_t w, uint32_t h)
}
}
ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID)
ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents)
{
TextureShaderDetails details = GetShaderDetails(texid, false);
@@ -2533,6 +2533,171 @@ ResourceId D3D11DebugManager::RenderOverlay(ResourceId texid, TextureDisplayOver
SAFE_RELEASE(os);
SAFE_RELEASE(rs);
}
else if(overlay == eTexOverlay_QuadOverdrawPass || overlay == eTexOverlay_QuadOverdrawDraw)
{
SCOPED_TIMER("Quad Overdraw");
vector<uint32_t> events = passEvents;
if(overlay == eTexOverlay_QuadOverdrawDraw)
{
events.clear();
events.push_back(eventID);
}
if(!events.empty())
{
if(overlay == eTexOverlay_QuadOverdrawPass)
m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_WithoutDraw);
D3D11RenderState *state = m_WrappedContext->GetCurrentPipelineState();
uint32_t width = 1920>>1;
uint32_t height = 1080>>1;
{
ID3D11Resource *res = NULL;
if(state->OM.RenderTargets[0])
{
state->OM.RenderTargets[0]->GetResource(&res);
}
else if(state->OM.DepthView)
{
state->OM.DepthView->GetResource(&res);
}
else
{
RDCERR("Couldn't get size of existing targets");
return m_OverlayResourceId;
}
D3D11_RESOURCE_DIMENSION dim;
res->GetType(&dim);
if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE1D)
{
D3D11_TEXTURE1D_DESC desc;
((ID3D11Texture1D *)res)->GetDesc(&desc);
width = desc.Width>>1;
height = 1;
}
else if(dim == D3D11_RESOURCE_DIMENSION_TEXTURE2D)
{
D3D11_TEXTURE2D_DESC desc;
((ID3D11Texture2D *)res)->GetDesc(&desc);
width = desc.Width>>1;
height = desc.Height>>1;
}
else
{
RDCERR("Trying to show quad overdraw on invalid view");
return m_OverlayResourceId;
}
SAFE_RELEASE(res);
}
D3D11_TEXTURE2D_DESC uavTexDesc = {
width, height, 1U, 4U,
DXGI_FORMAT_R32_UINT,
{ 1, 0 },
D3D11_USAGE_DEFAULT,
D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE,
0,
0,
};
ID3D11Texture2D *overdrawTex = NULL;
ID3D11ShaderResourceView *overdrawSRV = NULL;
ID3D11UnorderedAccessView *overdrawUAV = NULL;
m_WrappedDevice->CreateTexture2D(&uavTexDesc, NULL, &overdrawTex);
m_WrappedDevice->CreateShaderResourceView(overdrawTex, NULL, &overdrawSRV);
m_WrappedDevice->CreateUnorderedAccessView(overdrawTex, NULL, &overdrawUAV);
UINT val = 0;
m_WrappedContext->ClearUnorderedAccessViewUint(overdrawUAV, &val);
for(size_t i=0; i < events.size(); i++)
{
D3D11RenderState oldstate = *m_WrappedContext->GetCurrentPipelineState();
D3D11_DEPTH_STENCIL_DESC dsdesc = {
/*DepthEnable =*/ TRUE,
/*DepthWriteMask =*/ D3D11_DEPTH_WRITE_MASK_ALL,
/*DepthFunc =*/ D3D11_COMPARISON_LESS,
/*StencilEnable =*/ FALSE,
/*StencilReadMask =*/ D3D11_DEFAULT_STENCIL_READ_MASK,
/*StencilWriteMask =*/ D3D11_DEFAULT_STENCIL_WRITE_MASK,
/*FrontFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS },
/*BackFace =*/ { D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_STENCIL_OP_KEEP, D3D11_COMPARISON_ALWAYS },
};
ID3D11DepthStencilState *ds = NULL;
if(state->OM.DepthStencilState)
state->OM.DepthStencilState->GetDesc(&dsdesc);
dsdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
dsdesc.StencilWriteMask = 0;
m_WrappedDevice->CreateDepthStencilState(&dsdesc, &ds);
m_WrappedContext->OMSetDepthStencilState(ds, oldstate.OM.StencRef);
SAFE_RELEASE(ds);
UINT UAVcount = 0;
m_WrappedContext->OMSetRenderTargetsAndUnorderedAccessViews(0, NULL, oldstate.OM.DepthView, 0, 1, &overdrawUAV, &UAVcount);
m_pImmediateContext->PSSetShader(m_DebugRender.QuadOverdrawPS, NULL, 0);
m_WrappedDevice->ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw);
oldstate.ApplyState(m_WrappedContext);
if(overlay == eTexOverlay_QuadOverdrawPass)
{
m_WrappedDevice->ReplayLog(frameID, events[i], events[i], eReplay_OnlyDraw);
if(i+1 < events.size())
m_WrappedDevice->ReplayLog(frameID, events[i], events[i+1], eReplay_WithoutDraw);
}
}
// resolve pass
{
m_pImmediateContext->VSSetShader(m_DebugRender.FullscreenVS, NULL, 0);
m_pImmediateContext->PSSetShader(m_DebugRender.QOResolvePS, NULL, 0);
ID3D11Buffer *buf = MakeCBuffer((float *)&overdrawRamp[0].x, sizeof(Vec4f)*21);
m_pImmediateContext->PSSetConstantBuffers(0, 1, &buf);
m_pImmediateContext->OMSetRenderTargets(1, &rtv, NULL);
m_pImmediateContext->OMSetDepthStencilState(m_DebugRender.NoDepthState, 0);
m_pImmediateContext->OMSetBlendState(NULL, NULL, 0xffffffff);
m_pImmediateContext->RSSetState(m_DebugRender.RastState);
float clearColour[] = { 0.0f, 0.0f, 0.0f, 0.0f };
m_pImmediateContext->ClearRenderTargetView(rtv, clearColour);
ID3D11ShaderResourceView *srv = ((WrappedID3D11ShaderResourceView *)overdrawSRV)->GetReal();
m_pImmediateContext->PSSetShaderResources(0, 1, &srv);
m_pImmediateContext->Draw(3, 0);
}
SAFE_RELEASE(overdrawTex);
SAFE_RELEASE(overdrawSRV);
SAFE_RELEASE(overdrawUAV);
if(overlay == eTexOverlay_QuadOverdrawPass)
m_WrappedDevice->ReplayLog(frameID, 0, eventID, eReplay_WithoutDraw);
}
}
else if(preDrawDepth)
{
D3D11_DEPTH_STENCIL_DESC cur = {0};
+12 -9
View File
@@ -780,6 +780,9 @@ bool D3D11DebugManager::InitDebugRendering()
m_DebugRender.FullscreenVS = MakeVShader(displayhlsl.c_str(), "RENDERDOC_FullscreenVS", "vs_4_0");
m_DebugRender.OverlayPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_OverlayPS", "ps_4_0");
m_DebugRender.CheckerboardPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_CheckerboardPS", "ps_4_0");
m_DebugRender.QuadOverdrawPS = MakePShader(displayhlsl.c_str(), "RENDERDOC_QuadOverdrawPS", "ps_5_0");
m_DebugRender.QOResolvePS = MakePShader(displayhlsl.c_str(), "RENDERDOC_QOResolvePS", "ps_5_0");
string multisamplehlsl = GetEmbeddedResource(multisample_hlsl);
@@ -4223,7 +4226,7 @@ void D3D11DebugManager::InitPostVSBuffers(uint32_t frameID, uint32_t eventID)
}
}
void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg)
void D3D11DebugManager::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
{
DebugVertexCBuffer vertexData;
@@ -4299,9 +4302,9 @@ void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay
float nearp = 0.1f;
float farp = 1000.0f;
for(size_t i=0; i < eventID.size(); i++)
for(size_t i=0; i < events.size(); i++)
{
PostVSData data = GetPostVSBuffers(frameID, eventID[i]);
PostVSData data = GetPostVSBuffers(frameID, events[i]);
const PostVSData::StageData &stage = data.GetStage(cfg.type);
if(stage.buf && stage.nearPlane != stage.farPlane)
@@ -4339,15 +4342,15 @@ void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay
{
m_pImmediateContext->IASetInputLayout(m_DebugRender.GenericHomogLayout);
if(eventID.size() > 1)
if(events.size() > 1)
{
pixelData.WireframeColour = Vec3f(cfg.prevMeshColour.x, cfg.prevMeshColour.y, cfg.prevMeshColour.z);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
}
for(size_t i=0; i < eventID.size()-1; i++)
for(size_t i=0; i < events.size()-1; i++)
{
PostVSData data = GetPostVSBuffers(frameID, eventID[i]);
PostVSData data = GetPostVSBuffers(frameID, events[i]);
const PostVSData::StageData &stage = data.GetStage(cfg.type);
if(stage.buf)
@@ -4366,7 +4369,7 @@ void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay
pixelData.WireframeColour = Vec3f(cfg.currentMeshColour.x, cfg.currentMeshColour.y, cfg.currentMeshColour.z);
FillCBuffer(m_DebugRender.GenericPSCBuffer, (float *)&pixelData, sizeof(DebugPixelCBufferData));
PostVSData data = GetPostVSBuffers(frameID, eventID.back());
PostVSData data = GetPostVSBuffers(frameID, events.back());
const PostVSData::StageData &stage = data.GetStage(cfg.type);
if(stage.buf)
{
@@ -4544,7 +4547,7 @@ void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay
m_pImmediateContext->GSSetShader(m_DebugRender.MeshGS, NULL, 0);
}
m_WrappedDevice->ReplayLog(frameID, 0, eventID[0], eReplay_OnlyDraw);
m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw);
if(cfg.solidShadeMode == eShade_Lit)
m_pImmediateContext->GSSetShader(NULL, NULL, 0);
@@ -4563,7 +4566,7 @@ void D3D11DebugManager::RenderMesh(int frameID, vector<int> eventID, MeshDisplay
m_pImmediateContext->PSSetConstantBuffers(0, 1, &m_DebugRender.GenericPSCBuffer);
m_WrappedDevice->ReplayLog(frameID, 0, eventID[0], eReplay_OnlyDraw);
m_WrappedDevice->ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw);
}
}
+4 -2
View File
@@ -130,7 +130,7 @@ class D3D11DebugManager
bool SaveTexture(ResourceId tex, uint32_t saveMip, wstring path);
void RenderText(float x, float y, float size, const char *textfmt, ...);
void RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
ID3D11Buffer *MakeCBuffer(float *data, size_t size);
@@ -158,7 +158,7 @@ class D3D11DebugManager
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip);
// don't need to differentiate arrays as we treat everything
@@ -438,6 +438,8 @@ class D3D11DebugManager
ID3D11PixelShader *CopyMSToArrayPS, *CopyArrayToMSPS;
ID3D11PixelShader *FloatCopyMSToArrayPS, *FloatCopyArrayToMSPS;
ID3D11PixelShader *DepthCopyMSToArrayPS, *DepthCopyArrayToMSPS;
ID3D11PixelShader *QuadOverdrawPS, *QOResolvePS;
ID3D11Buffer *tileResultBuff, *resultBuff, *resultStageBuff;
ID3D11UnorderedAccessView *tileResultUAV[3], *resultUAV[3];
+4 -4
View File
@@ -1245,9 +1245,9 @@ bool D3D11Replay::SaveTexture(ResourceId tex, uint32_t saveMip, wstring path)
return m_pDevice->GetDebugManager()->SaveTexture(tex, saveMip, path);
}
void D3D11Replay::RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg)
void D3D11Replay::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
{
return m_pDevice->GetDebugManager()->RenderMesh(frameID, eventID, cfg);
return m_pDevice->GetDebugManager()->RenderMesh(frameID, events, cfg);
}
void D3D11Replay::BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors)
@@ -1316,9 +1316,9 @@ void D3D11Replay::PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t
m_pDevice->GetDebugManager()->PickPixel(texture, x, y, sliceFace, mip, pixel);
}
ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID)
ResourceId D3D11Replay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents)
{
return m_pDevice->GetDebugManager()->RenderOverlay(texid, overlay, frameID, eventID);
return m_pDevice->GetDebugManager()->RenderOverlay(texid, overlay, frameID, eventID, passEvents);
}
ResourceId D3D11Replay::ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip)
+2 -2
View File
@@ -101,7 +101,7 @@ class D3D11Replay : public IReplayDriver
ResourceId CreateProxyTexture(FetchTexture templateTex);
void SetProxyTextureData(ResourceId texid, uint32_t arrayIdx, uint32_t mip, byte *data, size_t dataSize);
void RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
bool RenderTexture(TextureDisplay cfg);
@@ -117,7 +117,7 @@ class D3D11Replay : public IReplayDriver
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID);
ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors);
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip);
+3 -3
View File
@@ -399,7 +399,7 @@ void GLReplay::RenderHighlightBox(float w, float h, float scale)
gl.glDrawArrays(eGL_LINE_LOOP, 0, 4);
}
ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID)
ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents)
{
WrappedOpenGL &gl = *m_pDriver;
@@ -635,7 +635,7 @@ ResourceId GLReplay::RenderOverlay(ResourceId texid, TextureDisplayOverlay overl
return m_pDriver->GetResourceManager()->GetID(TextureRes(ctx, DebugData.overlayTex));
}
void GLReplay::RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg)
void GLReplay::RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg)
{
WrappedOpenGL &gl = *m_pDriver;
@@ -745,7 +745,7 @@ void GLReplay::RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg)
gl.glDisable(eGL_DEPTH_TEST);
gl.glPolygonMode(eGL_FRONT_AND_BACK, eGL_LINE);
ReplayLog(frameID, 0, eventID[0], eReplay_OnlyDraw);
ReplayLog(frameID, 0, events[0], eReplay_OnlyDraw);
if(depthTest)
gl.glEnable(eGL_DEPTH_TEST);
+2 -2
View File
@@ -97,7 +97,7 @@ class GLReplay : public IReplayDriver
bool SaveTexture(ResourceId tex, uint32_t saveMip, wstring path);
void RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg);
void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg);
void BuildTargetShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors);
void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors);
@@ -117,7 +117,7 @@ class GLReplay : public IReplayDriver
ShaderDebugTrace DebugThread(uint32_t frameID, uint32_t eventID, uint32_t groupid[3], uint32_t threadid[3]);
void PickPixel(ResourceId texture, uint32_t x, uint32_t y, uint32_t sliceFace, uint32_t mip, float pixel[4]);
ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID);
ResourceId RenderOverlay(ResourceId cfg, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents);
ResourceId ApplyCustomShader(ResourceId shader, ResourceId texid, uint32_t mip);
ResourceId CreateProxyTexture(FetchTexture templateTex);
+26
View File
@@ -32,6 +32,32 @@
#include "matrix.h"
#include "quat.h"
// colour ramp from http://www.ncl.ucar.edu/Document/Graphics/ColorTables/GMT_wysiwyg.shtml
const Vec4f overdrawRamp[21] =
{
Vec4f(0.000000f, 0.000000f, 0.000000f, 0.0f),
Vec4f(0.250980f, 0.000000f, 0.250980f, 1.0f),
Vec4f(0.250980f, 0.000000f, 0.752941f, 1.0f),
Vec4f(0.000000f, 0.250980f, 1.000000f, 1.0f),
Vec4f(0.000000f, 0.501961f, 1.000000f, 1.0f),
Vec4f(0.000000f, 0.627451f, 1.000000f, 1.0f),
Vec4f(0.250980f, 0.752941f, 1.000000f, 1.0f),
Vec4f(0.250980f, 0.878431f, 1.000000f, 1.0f),
Vec4f(0.250980f, 1.000000f, 1.000000f, 1.0f),
Vec4f(0.250980f, 1.000000f, 0.752941f, 1.0f),
Vec4f(0.250980f, 1.000000f, 0.250980f, 1.0f),
Vec4f(0.501961f, 1.000000f, 0.250980f, 1.0f),
Vec4f(0.752941f, 1.000000f, 0.250980f, 1.0f),
Vec4f(1.000000f, 1.000000f, 0.250980f, 1.0f),
Vec4f(1.000000f, 0.878431f, 0.250980f, 1.0f),
Vec4f(1.000000f, 0.627451f, 0.250980f, 1.0f),
Vec4f(1.000000f, 0.376471f, 0.250980f, 1.0f),
Vec4f(1.000000f, 0.125490f, 0.250980f, 1.0f),
Vec4f(1.000000f, 0.376471f, 0.752941f, 1.0f),
Vec4f(1.000000f, 0.627451f, 1.000000f, 1.0f),
Vec4f(1.000000f, 0.878431f, 1.000000f, 1.0f),
};
static inline size_t matIdx(const size_t x, const size_t y) { return x+y*4; }
Matrix4f Matrix4f::Mul(const Matrix4f &o) const
+2
View File
@@ -75,6 +75,8 @@ struct Vec4f
float x, y, z, w;
};
extern const Vec4f overdrawRamp[21];
inline Vec3f operator *(const Vec3f &a, const float b)
{
return Vec3f(a.x*b, a.y*b, a.z*b);
+2 -2
View File
@@ -98,7 +98,7 @@ class IRemoteDriver
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;
virtual ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID) = 0;
virtual ResourceId RenderOverlay(ResourceId texid, TextureDisplayOverlay overlay, uint32_t frameID, uint32_t eventID, const vector<uint32_t> &passEvents) = 0;
virtual bool IsRenderOutput(ResourceId id) = 0;
@@ -130,7 +130,7 @@ class IReplayDriver : public IRemoteDriver
virtual bool SaveTexture(ResourceId tex, uint32_t saveMip, wstring path) = 0;
virtual void RenderMesh(int frameID, vector<int> eventID, MeshDisplay cfg) = 0;
virtual void RenderMesh(uint32_t frameID, const vector<uint32_t> &events, MeshDisplay cfg) = 0;
virtual bool RenderTexture(TextureDisplay cfg) = 0;
virtual void BuildCustomShader(string source, string entry, const uint32_t compileFlags, ShaderStageType type, ResourceId *id, string *errors) = 0;
+2
View File
@@ -123,6 +123,8 @@ enum TextureDisplayOverlay
eTexOverlay_ViewportScissor,
eTexOverlay_NaN,
eTexOverlay_Clipping,
eTexOverlay_QuadOverdrawPass,
eTexOverlay_QuadOverdrawDraw,
};
enum SpecialFormat
+79 -57
View File
@@ -93,6 +93,8 @@ bool ReplayOutput::SetTextureDisplay(const TextureDisplay &o)
bool ReplayOutput::SetMeshDisplay(const MeshDisplay &o)
{
if(o.thisDrawOnly!= m_RenderData.meshDisplay.thisDrawOnly)
m_OverlayDirty = true;
m_RenderData.meshDisplay = o;
m_MainOutput.dirty = true;
return true;
@@ -122,11 +124,40 @@ void ReplayOutput::RefreshOverlay()
{
FetchDrawcall *draw = m_pRenderer->GetDrawcallByEID(m_EventID, m_LastDeferredEvent);
{
passEvents.clear();
FetchDrawcall *start = draw;
while(start && start->previous != 0 && (m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous)->flags & eDraw_Clear) == 0)
{
FetchDrawcall *prev = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous);;
if(memcmp(start->outputs, prev->outputs, sizeof(start->outputs)) || start->depthOut != prev->depthOut)
break;
start = prev;
}
while(start)
{
if(start->flags & eDraw_Drawcall)
{
passEvents.push_back(start->eventID);
}
if(start == draw)
break;
start = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->next);
}
}
if(m_Config.m_Type == eOutputType_TexDisplay && m_RenderData.texDisplay.overlay != eTexOverlay_None)
{
if(draw && m_pDevice->IsRenderOutput(m_RenderData.texDisplay.texid))
{
m_OverlayResourceId = m_pDevice->RenderOverlay(m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), m_RenderData.texDisplay.overlay, m_FrameID, m_EventID);
m_OverlayResourceId = m_pDevice->RenderOverlay(m_pDevice->GetLiveID(m_RenderData.texDisplay.texid), m_RenderData.texDisplay.overlay,
m_FrameID, m_EventID, passEvents);
m_OverlayDirty = false;
}
}
@@ -142,36 +173,22 @@ void ReplayOutput::RefreshOverlay()
{
m_pDevice->InitPostVSBuffers(m_FrameID, draw->eventID);
}
else
else if(!passEvents.empty())
{
FetchDrawcall *start = draw;
while(start->previous != 0 && (m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous)->flags & eDraw_Clear) == 0)
start = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous);
m_pDevice->ReplayLog(m_FrameID, 0, start->eventID, eReplay_WithoutDraw);
uint32_t prev = passEvents[0];
uint32_t prev = start->eventID;
while(start)
for(size_t i=0; i < passEvents.size(); i++)
{
if(start->flags & eDraw_Drawcall)
if(prev != passEvents[i])
{
if(prev != start->eventID)
{
m_pDevice->ReplayLog(m_FrameID, prev, start->eventID, eReplay_WithoutDraw);
m_pDevice->ReplayLog(m_FrameID, prev, passEvents[i], eReplay_WithoutDraw);
prev = start->eventID;
}
m_pDevice->InitPostVSBuffers(m_FrameID, start->eventID);
prev = passEvents[i];
}
if(start == draw)
break;
start = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->next);
m_pDevice->InitPostVSBuffers(m_FrameID, passEvents[i]);
}
m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_WithoutDraw);
}
}
@@ -249,12 +266,38 @@ bool ReplayOutput::PickPixel(ResourceId tex, bool customShader, uint32_t x, uint
RDCEraseEl(ret->value_f);
bool decodeRamp = false;
if(customShader && m_RenderData.texDisplay.CustomShader != ResourceId() && m_CustomShaderResourceId != ResourceId())
{
tex = m_CustomShaderResourceId;
}
if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw ||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) &&
m_OverlayResourceId != ResourceId())
{
decodeRamp = true;
tex = m_OverlayResourceId;
}
m_pDevice->PickPixel(m_pDevice->GetLiveID(tex), x, y, sliceFace, mip, ret->value_f);
if(decodeRamp)
{
for(size_t c=0; c < ARRAY_COUNT(overdrawRamp); c++)
{
if(fabs(ret->value_f[0] - overdrawRamp[c].x) < 0.001f &&
fabs(ret->value_f[1] - overdrawRamp[c].y) < 0.001f &&
fabs(ret->value_f[2] - overdrawRamp[c].z) < 0.001f)
{
ret->value_i[0] = (int32_t)c;
ret->value_i[1] = 0;
ret->value_i[2] = 0;
ret->value_i[3] = 0;
break;
}
}
}
return true;
}
@@ -294,6 +337,11 @@ void ReplayOutput::DisplayContext()
if(m_RenderData.texDisplay.CustomShader != ResourceId())
disp.texid = m_CustomShaderResourceId;
if((m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawDraw ||
m_RenderData.texDisplay.overlay == eTexOverlay_QuadOverdrawPass) &&
m_OverlayResourceId != ResourceId())
disp.texid = m_OverlayResourceId;
disp.scale = 8.0f;
@@ -490,7 +538,14 @@ void ReplayOutput::DisplayMesh()
if(m_RenderData.meshDisplay.type == eMeshDataStage_Unknown) return;
if((draw->flags & eDraw_Drawcall) == 0) return;
vector<int> events;
vector<uint32_t> events = passEvents;
if(m_RenderData.meshDisplay.type == eMeshDataStage_VSIn ||
m_RenderData.meshDisplay.thisDrawOnly)
{
events.clear();
events.push_back(draw->eventID);
}
if(draw && m_OverlayDirty)
{
@@ -499,44 +554,11 @@ void ReplayOutput::DisplayMesh()
m_pDevice->ReplayLog(m_FrameID, 0, m_EventID, eReplay_OnlyDraw);
}
if(m_RenderData.meshDisplay.type != eMeshDataStage_VSIn)
{
if(m_RenderData.meshDisplay.thisDrawOnly)
{
events.push_back(draw->eventID);
}
else
{
FetchDrawcall *start = draw;
while(start->previous != 0 && (m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous)->flags & eDraw_Clear) == 0)
start = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->previous);
while(start)
{
if(start->flags & eDraw_Drawcall)
{
events.push_back(start->eventID);
}
if(start == draw)
break;
start = m_pRenderer->GetDrawcallByDrawID((uint32_t)start->next);
}
}
}
m_pDevice->BindOutputWindow(m_MainOutput.outputID, true);
m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0);
m_pDevice->RenderCheckerboard(Vec3f(0.666f, 0.666f, 0.666f), Vec3f(0.333f, 0.333f, 0.333f));
if(m_RenderData.meshDisplay.type == eMeshDataStage_VSIn)
{
events.clear();
events.push_back(draw->eventID);
}
RDCASSERT(!events.empty());
m_pDevice->ClearOutputWindowDepth(m_MainOutput.outputID, 1.0f, 0);
+2
View File
@@ -107,6 +107,8 @@ private:
uint32_t m_FirstDeferredEvent;
uint32_t m_LastDeferredEvent;
OutputConfig m_Config;
vector<uint32_t> passEvents;
int32_t m_Width;
int32_t m_Height;
+2
View File
@@ -125,6 +125,8 @@ namespace renderdoc
ViewportScissor,
NaN,
Clipping,
QuadOverdrawPass,
QuadOverdrawDraw,
};
public enum SpecialFormat
+3 -1
View File
@@ -554,7 +554,9 @@
"Stencil Test",
"Viewport/Scissor Region",
"NaN/INF/-ve Display",
"Clipping"});
"Clipping",
"Quad Overdraw (Pass)",
"Quad Overdraw (Draw)"});
this.overlay.Name = "overlay";
this.overlay.Size = new System.Drawing.Size(121, 25);
this.overlay.SelectedIndexChanged += new System.EventHandler(this.overlay_SelectedIndexChanged);
+8
View File
@@ -1331,6 +1331,14 @@ namespace renderdocui.Windows
bool uintTex = (tex.format.compType == FormatComponentType.UInt);
bool sintTex = (tex.format.compType == FormatComponentType.SInt);
if (m_TexDisplay.overlay == TextureDisplayOverlay.QuadOverdrawPass ||
m_TexDisplay.overlay == TextureDisplayOverlay.QuadOverdrawDraw)
{
dsv = false;
uintTex = false;
sintTex = true;
}
if (m_CurHoverValue != null)
{
if (dsv || uintTex || sintTex)