Add Spirv Debugger APIs to wrap API Wrapper APIs

The Debugger APIs run on the device thread if required,

FillInputValue(), ReadTexel(), WriteTexel()
This commit is contained in:
Jake Turner committed 2025-09-24 14:38:33 +01:00
1 parent 35fdf44c20
commit 8d9bb3f168
3 files changed
+133 -36

No files matched your search

+99 -36
View File
@@ -3796,8 +3796,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
{
// get current position
ShaderVariable curCoord(rdcstr(), 0.0f, 0.0f, 0.0f, 0.0f);
debugger.GetAPIWrapper()->FillInputValue(curCoord, ShaderBuiltin::Position, workgroupIndex,
0, 0);
debugger.FillInputValue(curCoord, ShaderBuiltin::Position, workgroupIndex);
// co-ords are relative to the current position
setUintComp(coord, 0, uintComp(coord, 0) + (uint32_t)floatComp(curCoord, 0));
@@ -3812,15 +3811,22 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
}
else
{
if(!debugger.GetAPIWrapper()->ReadTexel(img.GetBindIndex(), coord,
read.imageOperands.flags & ImageOperands::Sample
? uintComp(GetSrc(read.imageOperands.sample), 0)
: 0,
result))
DeviceOpResult opResult =
debugger.ReadTexel(img.GetBindIndex(), coord,
read.imageOperands.flags & ImageOperands::Sample
? uintComp(GetSrc(read.imageOperands.sample), 0)
: 0,
result);
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
set0001(result);
}
else if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
SetDst(read.result, result);
@@ -3837,11 +3843,15 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
// only the sample operand should be here
RDCASSERT((write.imageOperands.flags & ImageOperands::Sample) == write.imageOperands.flags);
debugger.GetAPIWrapper()->WriteTexel(img.GetBindIndex(), coord,
write.imageOperands.flags & ImageOperands::Sample
? uintComp(GetSrc(write.imageOperands.sample), 0)
: 0,
texel);
if(debugger.WriteTexel(img.GetBindIndex(), coord,
write.imageOperands.flags & ImageOperands::Sample
? uintComp(GetSrc(write.imageOperands.sample), 0)
: 0,
texel) == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
break;
}
@@ -4155,12 +4165,18 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
result.rows = result.columns = 1;
result.type = resultType.scalar().Type();
if(!debugger.GetAPIWrapper()->ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result))
DeviceOpResult opResult = debugger.ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
}
else if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
SetDst(load.result, result);
@@ -4183,8 +4199,12 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
}
else
{
debugger.GetAPIWrapper()->WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), value);
if(debugger.WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), value) == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
break;
@@ -4213,19 +4233,31 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
result.rows = result.columns = 1;
result.type = resultType.scalar().Type();
if(!debugger.GetAPIWrapper()->ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result))
DeviceOpResult opResult = debugger.ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(opResult == DeviceOpResult::NeedsDevice)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
SetStepNeedsDeviceThread();
break;
}
else
{
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
}
debugger.GetAPIWrapper()->WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), value);
if(debugger.WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), value) == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
}
SetDst(excg.result, result);
break;
}
case Op::AtomicCompareExchange:
@@ -4253,12 +4285,18 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
result.rows = result.columns = 1;
result.type = resultType.scalar().Type();
if(!debugger.GetAPIWrapper()->ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result))
DeviceOpResult opResult = debugger.ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
}
else if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
SetDst(cmpexcg.result, result);
@@ -4284,8 +4322,13 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
}
else
{
debugger.GetAPIWrapper()->WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), value);
DeviceOpResult opResult = debugger.WriteTexel(
ptr.members[0].GetBindIndex(), ptr.members[1], uintComp(ptr.members[2], 0), value);
if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
}
break;
@@ -4313,12 +4356,18 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
result.rows = result.columns = 1;
result.type = resultType.scalar().Type();
if(!debugger.GetAPIWrapper()->ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result))
DeviceOpResult opResult = debugger.ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
}
else if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
SetDst(atomic.result, result);
@@ -4341,8 +4390,12 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
}
else
{
debugger.GetAPIWrapper()->WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(debugger.WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result) == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
break;
}
@@ -4380,12 +4433,18 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
result.rows = result.columns = 1;
result.type = resultType.scalar().Type();
if(!debugger.GetAPIWrapper()->ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result))
DeviceOpResult opResult = debugger.ReadTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(opResult == DeviceOpResult::Failed)
{
// sample failed. Pretend we got 0 columns back
RDCEraseEl(result.value);
}
else if(opResult == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
SetDst(atomic.result, result);
@@ -4479,8 +4538,12 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
}
else
{
debugger.GetAPIWrapper()->WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result);
if(debugger.WriteTexel(ptr.members[0].GetBindIndex(), ptr.members[1],
uintComp(ptr.members[2], 0), result) == DeviceOpResult::NeedsDevice)
{
SetStepNeedsDeviceThread();
break;
}
}
break;
}
@@ -5041,7 +5104,7 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
void ThreadState::ExecuteMemoryBarrier(Id semanticsId)
{
// ignore if not the acitve thread
// ignore if not the active thread
if(!m_State)
return;
@@ -654,6 +654,11 @@ public:
uint64_t GetDeviceThreadID() const { return deviceThreadID; }
bool IsDeviceThread() const { return Threading::GetCurrentID() == GetDeviceThreadID(); }
void AddDebugMessage(MessageCategory cat, MessageSeverity sev, MessageSource src, rdcstr desc) const;
void FillInputValue(ShaderVariable &var, ShaderBuiltin builtin, uint32_t threadIndex) const;
DeviceOpResult ReadTexel(const ShaderBindIndex &imageBind, const ShaderVariable &coord,
uint32_t sample, ShaderVariable &output) const;
DeviceOpResult WriteTexel(const ShaderBindIndex &imageBind, const ShaderVariable &coord,
uint32_t sample, const ShaderVariable &input) const;
private:
virtual void PreParse(uint32_t maxId);
virtual void PostParse();
@@ -4897,6 +4897,35 @@ void Debugger::ProcessQueuedDeviceThreadSteps()
}
}
}
void Debugger::FillInputValue(ShaderVariable &var, ShaderBuiltin builtin, uint32_t threadIndex) const
{
apiWrapper->FillInputValue(var, builtin, threadIndex, 0, 0);
}
DeviceOpResult Debugger::ReadTexel(const ShaderBindIndex &imageBind, const ShaderVariable &coord,
uint32_t sample, ShaderVariable &output) const
{
if(Threading::GetCurrentID() == GetDeviceThreadID())
{
if(!apiWrapper->ReadTexel(imageBind, coord, sample, output))
return DeviceOpResult::Failed;
return DeviceOpResult::Succeeded;
}
return DeviceOpResult::NeedsDevice;
}
DeviceOpResult Debugger::WriteTexel(const ShaderBindIndex &imageBind, const ShaderVariable &coord,
uint32_t sample, const ShaderVariable &input) const
{
if(Threading::GetCurrentID() == GetDeviceThreadID())
{
if(!apiWrapper->WriteTexel(imageBind, coord, sample, input))
return DeviceOpResult::Failed;
return DeviceOpResult::Succeeded;
}
return DeviceOpResult::NeedsDevice;
}
}; // namespace rdcspv
#if ENABLED(ENABLE_UNIT_TESTS)