mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-26 16:36:31 +00:00
Spirv debugger support for queue and run of Simulation on Device Thread
This commit is contained in:
@@ -5142,3 +5142,16 @@ rdcstr DoStringise(const rdcspv::StepThreadMode &el)
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
};
|
||||
|
||||
template <>
|
||||
rdcstr DoStringise(const rdcspv::DeviceOpResult &el)
|
||||
{
|
||||
BEGIN_ENUM_STRINGISE(rdcspv::DeviceOpResult)
|
||||
{
|
||||
STRINGISE_ENUM_CLASS(Unknown)
|
||||
STRINGISE_ENUM_CLASS(Succeeded)
|
||||
STRINGISE_ENUM_CLASS(Failed)
|
||||
STRINGISE_ENUM_CLASS(NeedsDevice)
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
};
|
||||
|
||||
@@ -58,6 +58,14 @@ enum class ThreadProperty : uint32_t
|
||||
|
||||
ITERABLE_OPERATORS(ThreadProperty);
|
||||
|
||||
enum class DeviceOpResult : uint32_t
|
||||
{
|
||||
Unknown,
|
||||
Succeeded,
|
||||
Failed,
|
||||
NeedsDevice,
|
||||
};
|
||||
|
||||
inline void AtomicStore(int32_t *var, int32_t newVal)
|
||||
{
|
||||
int32_t oldVal = *var;
|
||||
@@ -372,6 +380,7 @@ struct ThreadState
|
||||
AtomicStore(&atomic_isSimulationStepActive, 1);
|
||||
AtomicStore(&atomic_stepNeedsGpuSampleGatherOp, 0);
|
||||
AtomicStore(&atomic_stepNeedsGpuMathOp, 0);
|
||||
AtomicStore(&atomic_stepNeedsDeviceThread, 0);
|
||||
}
|
||||
void SetStepNeedsGpuSampleGatherOp()
|
||||
{
|
||||
@@ -388,6 +397,12 @@ struct ThreadState
|
||||
SetPendingResultStatus(PendingResultStatus::Pending);
|
||||
}
|
||||
bool StepNeedsGpuMathOp() const { return (AtomicLoad(&atomic_stepNeedsGpuMathOp) == 1); }
|
||||
void SetStepNeedsDeviceThread()
|
||||
{
|
||||
AtomicStore(&atomic_stepNeedsDeviceThread, 1);
|
||||
SetPendingResultStatus(PendingResultStatus::Pending);
|
||||
}
|
||||
bool StepNeedsDeviceThread() const { return (AtomicLoad(&atomic_stepNeedsDeviceThread) == 1); }
|
||||
const GpuMathOperation &GetQueuedGpuMathOp() const
|
||||
{
|
||||
RDCASSERT(AtomicLoad(&atomic_stepNeedsGpuMathOp));
|
||||
@@ -455,6 +470,7 @@ private:
|
||||
int32_t atomic_pendingResultStatus = (int32_t)PendingResultStatus::Unknown;
|
||||
int32_t atomic_stepNeedsGpuSampleGatherOp = 0;
|
||||
int32_t atomic_stepNeedsGpuMathOp = 0;
|
||||
int32_t atomic_stepNeedsDeviceThread = 0;
|
||||
int32_t atomic_isSimulationStepActive = 0;
|
||||
};
|
||||
|
||||
@@ -757,6 +773,9 @@ private:
|
||||
void ClampScalars(const ShaderVariable &var, uint8_t &scalar0) const;
|
||||
void ClampScalars(const ShaderVariable &var, uint8_t &scalar0, uint8_t &scalar1) const;
|
||||
|
||||
void QueueDeviceThreadStep(uint32_t lane);
|
||||
void ProcessQueuedDeviceThreadSteps();
|
||||
|
||||
void QueueJob(uint32_t lane, rdcarray<ShaderDebugState> *ret);
|
||||
void StepThread(uint32_t lane, StepThreadMode stepMode, rdcarray<ShaderDebugState> *ret);
|
||||
void InternalStepThread(uint32_t lane, rdcarray<ShaderDebugState> *ret);
|
||||
@@ -772,6 +791,7 @@ private:
|
||||
mutable rdcarray<DebugMessage> queuedDebugMessages;
|
||||
rdcarray<bool> queuedGpuMathOps;
|
||||
rdcarray<bool> queuedGpuSampleGatherOps;
|
||||
rdcarray<bool> queuedDeviceThreadSteps;
|
||||
rdcarray<ShaderDebugState> *shaderChangesReturn;
|
||||
|
||||
bool retireIDs = true;
|
||||
@@ -792,3 +812,4 @@ void AssignValue(ShaderVariable &dst, const ShaderVariable &src);
|
||||
|
||||
DECLARE_REFLECTION_ENUM(rdcspv::ThreadState::PendingResultStatus);
|
||||
DECLARE_REFLECTION_ENUM(rdcspv::StepThreadMode);
|
||||
DECLARE_REFLECTION_ENUM(rdcspv::DeviceOpResult);
|
||||
|
||||
@@ -1024,12 +1024,14 @@ ShaderDebugTrace *Debugger::BeginDebug(DebugAPIWrapper *api, const ShaderStage s
|
||||
stage = shaderStage;
|
||||
apiWrapper = api;
|
||||
|
||||
queuedDeviceThreadSteps.resize(threadsInWorkgroup);
|
||||
queuedGpuMathOps.resize(threadsInWorkgroup);
|
||||
queuedGpuSampleGatherOps.resize(threadsInWorkgroup);
|
||||
pendingLanes.resize(threadsInWorkgroup);
|
||||
for(uint32_t i = 0; i < threadsInWorkgroup; i++)
|
||||
{
|
||||
workgroup.push_back(ThreadState(*this, global));
|
||||
queuedDeviceThreadSteps[i] = false;
|
||||
queuedGpuMathOps[i] = false;
|
||||
queuedGpuSampleGatherOps[i] = false;
|
||||
pendingLanes[i] = false;
|
||||
@@ -2693,6 +2695,7 @@ rdcarray<ShaderDebugState> Debugger::ContinueDebug()
|
||||
do
|
||||
{
|
||||
ProcessQueuedDebugMessages();
|
||||
ProcessQueuedDeviceThreadSteps();
|
||||
// Convert the simulation threads queued operations into pending operations i.e. GPU commands
|
||||
ProcessQueuedOps();
|
||||
// Sync any pending GPU operations and set the results to the pending threads
|
||||
@@ -4669,6 +4672,8 @@ void Debugger::StepThread(uint32_t lane, StepThreadMode stepMode, rdcarray<Shade
|
||||
break;
|
||||
else if(thread.StepNeedsGpuMathOp())
|
||||
break;
|
||||
else if(thread.StepNeedsDeviceThread())
|
||||
break;
|
||||
|
||||
if(isActiveThread)
|
||||
curActiveSteps++;
|
||||
@@ -4695,6 +4700,12 @@ void Debugger::StepThread(uint32_t lane, StepThreadMode stepMode, rdcarray<Shade
|
||||
QueueGpuMathOp(lane);
|
||||
return;
|
||||
}
|
||||
if(thread.StepNeedsDeviceThread())
|
||||
{
|
||||
RDCASSERT(!simulateStep);
|
||||
QueueDeviceThreadStep(lane);
|
||||
return;
|
||||
}
|
||||
RDCASSERT(!thread.IsPendingResultPending());
|
||||
thread.SetSimulationStepCompleted();
|
||||
}
|
||||
@@ -4744,6 +4755,8 @@ void Debugger::InternalStepThread(uint32_t lane, rdcarray<ShaderDebugState> *ret
|
||||
return;
|
||||
if(thread.StepNeedsGpuMathOp())
|
||||
return;
|
||||
if(thread.StepNeedsDeviceThread())
|
||||
return;
|
||||
|
||||
if(!thread.IsPendingResultPending())
|
||||
{
|
||||
@@ -4821,6 +4834,8 @@ void Debugger::InternalStepThread(uint32_t lane, rdcarray<ShaderDebugState> *ret
|
||||
return;
|
||||
if(thread.StepNeedsGpuMathOp())
|
||||
return;
|
||||
if(thread.StepNeedsDeviceThread())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4856,6 +4871,32 @@ void Debugger::AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSou
|
||||
queuedDebugMessages.push_back({c, sv, src, d});
|
||||
}
|
||||
|
||||
// Can be called from any thread
|
||||
void Debugger::QueueDeviceThreadStep(uint32_t lane)
|
||||
{
|
||||
ThreadState &thread = workgroup[lane];
|
||||
RDCASSERT(thread.IsSimulationStepActive());
|
||||
thread.SetStepQueued();
|
||||
RDCASSERT(!queuedDeviceThreadSteps[lane]);
|
||||
queuedDeviceThreadSteps[lane] = true;
|
||||
}
|
||||
|
||||
// Must be called from the replay manager thread (the debugger thread)
|
||||
void Debugger::ProcessQueuedDeviceThreadSteps()
|
||||
{
|
||||
CHECK_DEBUGGER_THREAD();
|
||||
for(uint32_t lane = 0; lane < queuedDeviceThreadSteps.size(); ++lane)
|
||||
{
|
||||
if(queuedDeviceThreadSteps[lane])
|
||||
{
|
||||
queuedDeviceThreadSteps[lane] = false;
|
||||
ThreadState &thread = workgroup[lane];
|
||||
thread.SetPendingResultUnknown();
|
||||
RDCASSERT(thread.IsSimulationStepActive());
|
||||
StepThread(lane, StepThreadMode::QUEUE_MULTIPLE_STEPS, shaderChangesReturn);
|
||||
}
|
||||
}
|
||||
}
|
||||
}; // namespace rdcspv
|
||||
|
||||
#if ENABLED(ENABLE_UNIT_TESTS)
|
||||
|
||||
Reference in New Issue
Block a user