Skip to content

Commit

Permalink
VK Shader Debugger support for Buffer Device Address
Browse files Browse the repository at this point in the history
  • Loading branch information
Zorro666 committed Jan 17, 2024
1 parent b23e9f6 commit c4e3f96
Show file tree
Hide file tree
Showing 9 changed files with 516 additions and 105 deletions.
68 changes: 57 additions & 11 deletions renderdoc/driver/shaders/spirv/spirv_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ inline uint64_t CountOnes(uint64_t value)
namespace rdcspv
{
const BindpointIndex DebugAPIWrapper::invalidBind = BindpointIndex(-12345, -12345, ~0U);
const BindpointIndex DebugAPIWrapper::pointerBind = BindpointIndex(-12345, -67890, ~0U);

ThreadState::ThreadState(uint32_t workgroupIdx, Debugger &debug, const GlobalState &globalState)
: debugger(debug), global(globalState)
Expand Down Expand Up @@ -256,6 +257,8 @@ void ThreadState::WritePointerValue(Id pointer, const ShaderVariable &val)
// if var is a pointer we update the underlying storage and generate at least one change,
// plus any additional ones for other pointers.
Id ptrid = debugger.GetPointerBaseId(var);
if(ptrid == Id())
ptrid = pointer;

// only track local writes when we don't have debug info, so we can track variables first
// becoming alive
Expand All @@ -265,7 +268,7 @@ void ThreadState::WritePointerValue(Id pointer, const ShaderVariable &val)

ShaderVariableChange basechange;

if(debugger.IsOpaquePointer(ids[ptrid]))
if(debugger.IsOpaquePointer(ids[ptrid]) || debugger.IsPhysicalPointer(ids[ptrid]))
{
// if this is a write to a SSBO pointer, don't record any alias changes, just record a no-op
// change to this pointer
Expand Down Expand Up @@ -355,7 +358,7 @@ void ThreadState::SetDst(Id id, const ShaderVariable &val)
auto it = std::lower_bound(live.begin(), live.end(), id);
live.insert(it - live.begin(), id);

if(val.type == VarType::GPUPointer)
if(val.type == VarType::GPUPointer && !debugger.IsPhysicalPointer(val))
{
Id ptrId = debugger.GetPointerBaseId(val);
if(ptrId != Id() && ptrId != id)
Expand Down Expand Up @@ -392,7 +395,8 @@ void ThreadState::ProcessScopeChange(const rdcarray<Id> &oldLive, const rdcarray

m_State->changes.push_back({debugger.GetPointerValue(ids[id])});

if(ids[id].type == VarType::GPUPointer && !debugger.IsOpaquePointer(ids[id]))
if(ids[id].type == VarType::GPUPointer && !debugger.IsOpaquePointer(ids[id]) &&
!debugger.IsPhysicalPointer(ids[id]))
{
Id ptrId = debugger.GetPointerBaseId(ids[id]);
pointersForId[ptrId].removeOne(id);
Expand Down Expand Up @@ -699,7 +703,28 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>

SetDst(chain.result, debugger.MakeCompositePointer(
ids[chain.base], debugger.GetPointerBaseId(ids[chain.base]), indices));
break;
}
case Op::PtrAccessChain:
case Op::InBoundsPtrAccessChain:
{
OpPtrAccessChain chain(it);

rdcarray<uint32_t> indices;
// evaluate the indices
indices.reserve(chain.indexes.size());
for(Id id : chain.indexes)
indices.push_back(uintComp(GetSrc(id), 0));

ShaderVariable base = ids[chain.base];
PointerVal val = base.GetPointer();
int32_t element = intComp(GetSrc(chain.element), 0);
// adjust the address by the element. We should have the array stride since the base pointer
// must point into an array and we can't go outside it.
base.SetTypedPointer(val.pointer + element * debugger.GetPointerArrayStride(base), val.shader,
val.pointerTypeID);
SetDst(chain.result,
debugger.MakeCompositePointer(base, debugger.GetPointerBaseId(base), indices));
break;
}
case Op::ArrayLength:
Expand All @@ -708,6 +733,9 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>

ShaderVariable structPointer = GetSrc(len.structure);

// "Structure must be a logical pointer..." which is opaqaue in RD terminolgoy
RDCASSERT(debugger.IsOpaquePointer(structPointer));

// get the pointer base offset (should be zero for any binding but could be non-zero for a
// buffer_device_address pointer)
uint64_t offset = debugger.GetPointerByteOffset(structPointer);
Expand Down Expand Up @@ -760,6 +788,24 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
SetDst(equal.result, var);
break;
}
// physical storage pointers
case Op::ConvertPtrToU:
{
OpConvertPtrToU convert(it);
ShaderVariable ptr = GetSrc(convert.pointer);
const DataType &resultType = debugger.GetType(convert.resultType);
ptr.type = resultType.scalar().Type();
SetDst(convert.result, ptr);
break;
}
case Op::ConvertUToPtr:
{
OpConvertUToPtr convert(it);
ShaderVariable ptr = GetSrc(convert.integerValue);
const DataType &type = debugger.GetType(convert.resultType);
SetDst(convert.result, debugger.MakeTypedPointer(ptr.value.u64v[0], type));
break;
}

//////////////////////////////////////////////////////////////////////////////
//
Expand Down Expand Up @@ -1280,7 +1326,12 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
const DataType &type = debugger.GetType(cast.resultType);
ShaderVariable var = GetSrc(cast.operand);

if((type.type == DataType::ScalarType && var.columns == 1) || type.vector().count == var.columns)
if(type.type == DataType::PointerType)
{
var = debugger.MakeTypedPointer(var.value.u64v[0], type);
}
else if((type.type == DataType::ScalarType && var.columns == 1) ||
type.vector().count == var.columns)
{
// if the column count is unchanged, just change the underlying type
var.type = type.scalar().Type();
Expand Down Expand Up @@ -3577,16 +3628,11 @@ void ThreadState::StepNext(ShaderDebugState *state, const rdcarray<ThreadState>
break;
}

// TODO physical storage pointers
case Op::ConvertPtrToU:
case Op::ConvertUToPtr:
case Op::PtrAccessChain:
case Op::InBoundsPtrAccessChain:
case Op::PtrDiff:
{
RDCERR(
"Physical storage pointers not supported. SPIR-V should have been rejected by "
"capability!");
"Variable pointers are not supported, PtrDiff must only be used with variable pointers, "
"not physical pointers");

ShaderVariable var("", 0U, 0U, 0U, 0U);
var.columns = 1;
Expand Down
13 changes: 13 additions & 0 deletions renderdoc/driver/shaders/spirv/spirv_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,17 @@ class DebugAPIWrapper
virtual ~DebugAPIWrapper() {}
virtual void AddDebugMessage(MessageCategory c, MessageSeverity sv, MessageSource src, rdcstr d) = 0;

virtual ResourceId GetShaderID() = 0;

virtual uint64_t GetBufferLength(BindpointIndex bind) = 0;

virtual void ReadBufferValue(BindpointIndex bind, uint64_t offset, uint64_t byteSize, void *dst) = 0;
virtual void WriteBufferValue(BindpointIndex bind, uint64_t offset, uint64_t byteSize,
const void *src) = 0;

virtual void ReadAddress(uint64_t address, uint64_t byteSize, void *dst) = 0;
virtual void WriteAddress(uint64_t address, uint64_t byteSize, const void *src) = 0;

virtual bool ReadTexel(BindpointIndex imageBind, const ShaderVariable &coord, uint32_t sample,
ShaderVariable &output) = 0;
virtual bool WriteTexel(BindpointIndex imageBind, const ShaderVariable &coord, uint32_t sample,
Expand All @@ -78,6 +83,7 @@ class DebugAPIWrapper
};

static const BindpointIndex invalidBind;
static const BindpointIndex pointerBind;

virtual bool CalculateSampleGather(ThreadState &lane, Op opcode, TextureType texType,
BindpointIndex imageBind, BindpointIndex samplerBind,
Expand Down Expand Up @@ -383,8 +389,12 @@ class Debugger : public Processor, public ShaderDebugger
DebugAPIWrapper::TextureType GetTextureType(const ShaderVariable &img) const;
ShaderVariable MakePointerVariable(Id id, const ShaderVariable *v, uint8_t scalar0 = 0xff,
uint8_t scalar1 = 0xff) const;
ShaderVariable MakeTypedPointer(uint64_t value, const DataType &type) const;
Id GetPointerBaseId(const ShaderVariable &v) const;
uint32_t GetPointerArrayStride(const ShaderVariable &ptr) const;
bool IsOpaquePointer(const ShaderVariable &v) const;
bool IsPhysicalPointer(const ShaderVariable &v) const;

bool ArePointersAndEqual(const ShaderVariable &a, const ShaderVariable &b) const;
void WriteThroughPointer(ShaderVariable &ptr, const ShaderVariable &val);
ShaderVariable MakeCompositePointer(const ShaderVariable &base, Id id, rdcarray<uint32_t> &indices);
Expand Down Expand Up @@ -453,6 +463,9 @@ class Debugger : public Processor, public ShaderDebugger

SparseIdMap<uint32_t> labelInstruction;

SparseIdMap<uint16_t> idToPointerType;
rdcarray<rdcspv::Id> pointerTypeToId;

// the live mutable global variables, to initialise a stack frame's live list
rdcarray<Id> liveGlobals;

Expand Down
Loading

0 comments on commit c4e3f96

Please sign in to comment.