mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-04 17:10:47 +00:00
Reset state in D3D shader debugging to before draw when fetching UAVs
* Debugging shaders with UAV access could(likely will) have side-effects on those UAV contents, so when ContinueDebug needs to fetch UAV contents we should replay back to before the draw to fetch them. * This replay only happens once per ContinueDebug, and UAV contents are cached globally so we only do it once per UAV that's accessed, so the impact is low.
This commit is contained in:
@@ -54,7 +54,8 @@ class D3D11DebugAPIWrapper : public DXBCDebug::DebugAPIWrapper
|
||||
{
|
||||
public:
|
||||
D3D11DebugAPIWrapper(WrappedID3D11Device *device, const DXBC::DXBCContainer *dxbc,
|
||||
DXBCDebug::GlobalState &globalState);
|
||||
DXBCDebug::GlobalState &globalState, uint32_t eid);
|
||||
~D3D11DebugAPIWrapper();
|
||||
|
||||
void SetCurrentInstruction(uint32_t instruction) { m_instruction = instruction; }
|
||||
void AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src, rdcstr d);
|
||||
@@ -86,15 +87,30 @@ private:
|
||||
const DXBC::DXBCContainer *m_dxbc;
|
||||
DXBCDebug::GlobalState &m_globalState;
|
||||
uint32_t m_instruction;
|
||||
uint32_t m_EventID;
|
||||
bool m_DidReplay = false;
|
||||
};
|
||||
|
||||
D3D11DebugAPIWrapper::D3D11DebugAPIWrapper(WrappedID3D11Device *device,
|
||||
const DXBC::DXBCContainer *dxbc,
|
||||
DXBCDebug::GlobalState &globalState)
|
||||
: m_pDevice(device), m_dxbc(dxbc), m_globalState(globalState), m_instruction(0)
|
||||
DXBCDebug::GlobalState &globalState, uint32_t eid)
|
||||
: m_pDevice(device), m_dxbc(dxbc), m_globalState(globalState), m_instruction(0), m_EventID(eid)
|
||||
{
|
||||
}
|
||||
|
||||
D3D11DebugAPIWrapper::~D3D11DebugAPIWrapper()
|
||||
{
|
||||
// if we replayed to before the draw for fetching some UAVs, replay back to after the draw to keep
|
||||
// the state consistent.
|
||||
if(m_DidReplay)
|
||||
{
|
||||
D3D11MarkerRegion region("ResetReplay");
|
||||
// replay the draw to get back to 'normal' state for this event, and mark that we need to
|
||||
// replay back to pristine state next time we need to fetch data.
|
||||
m_pDevice->ReplayLog(0, m_EventID, eReplay_OnlyDraw);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D11DebugAPIWrapper::AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src,
|
||||
rdcstr d)
|
||||
{
|
||||
@@ -178,6 +194,15 @@ bool D3D11DebugAPIWrapper::FetchSRV(const DXBCDebug::BindingSlot &slot)
|
||||
|
||||
bool D3D11DebugAPIWrapper::FetchUAV(const DXBCDebug::BindingSlot &slot)
|
||||
{
|
||||
// if the UAV might be dirty from side-effects from the draw, replay back to right
|
||||
// before it.
|
||||
if(!m_DidReplay)
|
||||
{
|
||||
D3D11MarkerRegion region("un-dirtying resources");
|
||||
m_pDevice->ReplayLog(0, m_EventID, eReplay_WithoutDraw);
|
||||
m_DidReplay = true;
|
||||
}
|
||||
|
||||
RDCASSERT(slot.registerSpace == 0);
|
||||
RDCASSERT(slot.shaderRegister < D3D11_1_UAV_SLOT_COUNT);
|
||||
|
||||
@@ -1802,6 +1827,7 @@ ShaderDebugTrace *D3D11Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui
|
||||
}
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, vs->GetMapping(), 0);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -2714,6 +2740,7 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position,
|
||||
tracker.State().ApplyState(m_pImmediateContext);
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, ps->GetMapping(), destIdx);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -2868,6 +2895,7 @@ ShaderDebugTrace *D3D11Replay::DebugThread(uint32_t eventId, const uint32_t grou
|
||||
D3D11RenderState *rs = m_pImmediateContext->GetCurrentPipelineState();
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, cs->GetMapping(), 0);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -2948,7 +2976,8 @@ rdcarray<ShaderDebugState> D3D11Replay::ContinueDebug(ShaderDebugger *debugger)
|
||||
if(!interpreter)
|
||||
return NULL;
|
||||
|
||||
D3D11DebugAPIWrapper apiWrapper(m_pDevice, interpreter->dxbc, interpreter->global);
|
||||
D3D11DebugAPIWrapper apiWrapper(m_pDevice, interpreter->dxbc, interpreter->global,
|
||||
interpreter->eventId);
|
||||
|
||||
D3D11MarkerRegion region("ContinueDebug Simulation Loop");
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ class D3D12DebugAPIWrapper : public DXBCDebug::DebugAPIWrapper
|
||||
{
|
||||
public:
|
||||
D3D12DebugAPIWrapper(WrappedID3D12Device *device, const DXBC::DXBCContainer *dxbc,
|
||||
DXBCDebug::GlobalState &globalState);
|
||||
DXBCDebug::GlobalState &globalState, uint32_t eid);
|
||||
~D3D12DebugAPIWrapper();
|
||||
|
||||
void SetCurrentInstruction(uint32_t instruction) { m_instruction = instruction; }
|
||||
void AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src, rdcstr d);
|
||||
@@ -97,15 +98,30 @@ private:
|
||||
const DXBC::DXBCContainer *m_dxbc;
|
||||
DXBCDebug::GlobalState &m_globalState;
|
||||
uint32_t m_instruction;
|
||||
uint32_t m_EventID;
|
||||
bool m_DidReplay = false;
|
||||
};
|
||||
|
||||
D3D12DebugAPIWrapper::D3D12DebugAPIWrapper(WrappedID3D12Device *device,
|
||||
const DXBC::DXBCContainer *dxbc,
|
||||
DXBCDebug::GlobalState &globalState)
|
||||
: m_pDevice(device), m_dxbc(dxbc), m_globalState(globalState), m_instruction(0)
|
||||
DXBCDebug::GlobalState &globalState, uint32_t eid)
|
||||
: m_pDevice(device), m_dxbc(dxbc), m_globalState(globalState), m_instruction(0), m_EventID(eid)
|
||||
{
|
||||
}
|
||||
|
||||
D3D12DebugAPIWrapper::~D3D12DebugAPIWrapper()
|
||||
{
|
||||
// if we replayed to before the draw for fetching some UAVs, replay back to after the draw to keep
|
||||
// the state consistent.
|
||||
if(m_DidReplay)
|
||||
{
|
||||
D3D12MarkerRegion region(m_pDevice->GetQueue()->GetReal(), "ResetReplay");
|
||||
// replay the draw to get back to 'normal' state for this event, and mark that we need to
|
||||
// replay back to pristine state next time we need to fetch data.
|
||||
m_pDevice->ReplayLog(0, m_EventID, eReplay_OnlyDraw);
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12DebugAPIWrapper::AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src,
|
||||
rdcstr d)
|
||||
{
|
||||
@@ -258,6 +274,15 @@ bool D3D12DebugAPIWrapper::FetchSRV(const DXBCDebug::BindingSlot &slot)
|
||||
}
|
||||
bool D3D12DebugAPIWrapper::FetchUAV(const DXBCDebug::BindingSlot &slot)
|
||||
{
|
||||
// if the UAV might be dirty from side-effects from the draw, replay back to right
|
||||
// before it.
|
||||
if(!m_DidReplay)
|
||||
{
|
||||
D3D12MarkerRegion region(m_pDevice->GetQueue()->GetReal(), "un-dirtying resources");
|
||||
m_pDevice->ReplayLog(0, m_EventID, eReplay_WithoutDraw);
|
||||
m_DidReplay = true;
|
||||
}
|
||||
|
||||
const D3D12RenderState &rs = m_pDevice->GetQueue()->GetCommandData()->m_RenderState;
|
||||
D3D12ResourceManager *rm = m_pDevice->GetResourceManager();
|
||||
|
||||
@@ -1860,6 +1885,7 @@ ShaderDebugTrace *D3D12Replay::DebugVertex(uint32_t eventId, uint32_t vertid, ui
|
||||
}
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, vs->GetMapping(), 0);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -2801,6 +2827,7 @@ void ExtractInputsPS(PSInput IN, float4 debug_pixelPos : SV_Position,
|
||||
}
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, origPSO->PS()->GetMapping(), destIdx);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -2960,6 +2987,7 @@ ShaderDebugTrace *D3D12Replay::DebugThread(uint32_t eventId, const uint32_t grou
|
||||
m_pDevice->GetResourceManager()->GetCurrentAs<WrappedID3D12PipelineState>(rs.pipe);
|
||||
|
||||
InterpretDebugger *interpreter = new InterpretDebugger;
|
||||
interpreter->eventId = eventId;
|
||||
ShaderDebugTrace *ret = interpreter->BeginDebug(dxbc, refl, pso->CS()->GetMapping(), 0);
|
||||
GlobalState &global = interpreter->global;
|
||||
ThreadState &state = interpreter->activeLane();
|
||||
@@ -3040,7 +3068,8 @@ rdcarray<ShaderDebugState> D3D12Replay::ContinueDebug(ShaderDebugger *debugger)
|
||||
if(!interpreter)
|
||||
return NULL;
|
||||
|
||||
D3D12DebugAPIWrapper apiWrapper(m_pDevice, interpreter->dxbc, interpreter->global);
|
||||
D3D12DebugAPIWrapper apiWrapper(m_pDevice, interpreter->dxbc, interpreter->global,
|
||||
interpreter->eventId);
|
||||
|
||||
D3D12MarkerRegion region(m_pDevice->GetQueue()->GetReal(), "ContinueDebug Simulation Loop");
|
||||
|
||||
|
||||
@@ -334,6 +334,7 @@ struct InterpretDebugger : public ShaderDebugger
|
||||
const ShaderBindpointMapping &mapping, int activeIndex);
|
||||
|
||||
GlobalState global;
|
||||
uint32_t eventId;
|
||||
|
||||
rdcarray<ThreadState> workgroup;
|
||||
|
||||
|
||||
@@ -37,11 +37,13 @@ RWTexture2D<uint> texout : register(u0);
|
||||
[numthreads(1,1,1)]
|
||||
void main()
|
||||
{
|
||||
texout[uint2(5,5)] = texout[uint2(4,4)] * 10;
|
||||
texout[uint2(3,4)] = texin[uint2(4,3)];
|
||||
texout[uint2(4,4)] = texin[uint2(3,3)];
|
||||
texout[uint2(4,3)] = texin[uint2(3,4)];
|
||||
texout[uint2(3,3)] = texin[uint2(4,4)];
|
||||
texout[uint2(0,0)] = texin[uint2(0,0)] + 3;
|
||||
texout[uint2(6,6)] = texout[uint2(5,5)] * 10;
|
||||
}
|
||||
|
||||
)EOSHADER";
|
||||
@@ -61,8 +63,8 @@ void main()
|
||||
}
|
||||
|
||||
ID3D11Texture2DPtr tex[2] = {
|
||||
MakeTexture(DXGI_FORMAT_R32_UINT, 8, 8).SRV().UAV(),
|
||||
MakeTexture(DXGI_FORMAT_R32_UINT, 8, 8).SRV().UAV(),
|
||||
MakeTexture(DXGI_FORMAT_R32_UINT, 8, 8).SRV().UAV().RTV(),
|
||||
MakeTexture(DXGI_FORMAT_R32_UINT, 8, 8).SRV().UAV().RTV(),
|
||||
};
|
||||
ID3D11ShaderResourceViewPtr srv[2] = {
|
||||
MakeSRV(tex[0]), MakeSRV(tex[1]),
|
||||
@@ -70,12 +72,18 @@ void main()
|
||||
ID3D11UnorderedAccessViewPtr uav[2] = {
|
||||
MakeUAV(tex[0]), MakeUAV(tex[1]),
|
||||
};
|
||||
ID3D11RenderTargetViewPtr texRTV = MakeRTV(tex[0]);
|
||||
|
||||
for(int i = 0; i < 2; i++)
|
||||
ctx->UpdateSubresource(tex[i], 0, NULL, data, sizeof(uint32_t) * 8, sizeof(uint32_t) * 8 * 8);
|
||||
|
||||
while(Running())
|
||||
{
|
||||
ctx->ClearState();
|
||||
|
||||
float black[4] = {};
|
||||
ctx->ClearRenderTargetView(texRTV, black);
|
||||
|
||||
float col[] = {0.2f, 0.2f, 0.2f, 1.0f};
|
||||
ctx->ClearRenderTargetView(bbRTV, col);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user