Skip to content

Commit

Permalink
DXIL Debugger new struct ResourceReferencceInfo for resource details
Browse files Browse the repository at this point in the history
Replaces previous use of DXIL::ResourceReference* which is only available for direct bindings
  • Loading branch information
Zorro666 committed Dec 3, 2024
1 parent 3de21cd commit aa548b3
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 74 deletions.
168 changes: 99 additions & 69 deletions renderdoc/driver/shaders/dxil/dxil_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1437,6 +1437,39 @@ void ApplyAllDerivatives(GlobalState &global, rdcarray<ThreadState> &quad, int d
}
}

void ResourceReferenceInfo::Create(const DXIL::ResourceReference *resRef, uint32_t arrayIndex)
{
resClass = resRef->resourceBase.resClass;
binding = BindingSlot(resRef->resourceBase.regBase + arrayIndex, resRef->resourceBase.space);
switch(resClass)
{
case DXIL::ResourceClass::SRV:
{
srvData.dim = (DXDebug::ResourceDimension)ConvertResourceKindToResourceDimension(
resRef->resourceBase.srvData.shape);
srvData.sampleCount = resRef->resourceBase.srvData.sampleCount;
srvData.compType = (DXDebug::ResourceRetType)ConvertComponentTypeToResourceRetType(
resRef->resourceBase.srvData.compType);
break;
}
case DXIL::ResourceClass::UAV:
{
break;
}
case DXIL::ResourceClass::CBuffer:
{
break;
}
case DXIL::ResourceClass::Sampler:
{
samplerData.samplerMode =
ConvertSamplerKindToSamplerMode(resRef->resourceBase.samplerData.samplerType);
break;
}
default: RDCERR("Unexpected resource class %s", ToStr(resClass).c_str()); break;
}
}

void MemoryTracking::AllocateMemoryForType(const DXIL::Type *type, Id allocId, bool global,
ShaderVariable &var)
{
Expand Down Expand Up @@ -1695,14 +1728,12 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
{
// GetDimensions(handle,mipLevel)
Id handleId = GetArgumentId(1);
ShaderBindIndex bindIndex;
bool annotatedHandle;
const DXIL::ResourceReference *resRef = GetResource(handleId, bindIndex, annotatedHandle);
if(!resRef)
ResourceReferenceInfo resRefInfo = GetResource(handleId, annotatedHandle);
if(!resRefInfo.Valid())
break;

BindingSlot binding(resRef->resourceBase.regBase + bindIndex.arrayElement,
resRef->resourceBase.space);
BindingSlot binding(resRefInfo.binding);
ShaderVariable data;
uint32_t mipLevel = 0;
if(!isUndef(inst.args[2]))
Expand All @@ -1712,8 +1743,8 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
mipLevel = arg.value.u32v[0];
}
int dim;
data = apiWrapper->GetResourceInfo(resRef->resourceBase.resClass, binding, mipLevel,
m_ShaderType, dim);
data = apiWrapper->GetResourceInfo(resRefInfo.resClass, binding, mipLevel, m_ShaderType,
dim);
// Returns a vector with: w, h, d, numLevels
result.value = data.value;
// DXIL reports the vector result as a struct of 4 x int.
Expand All @@ -1731,18 +1762,15 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
{
// Texture2DMSGetSamplePosition(srv,index)
Id handleId = GetArgumentId(1);
ShaderBindIndex bindIndex;
bool annotatedHandle;
const DXIL::ResourceReference *resRef = GetResource(handleId, bindIndex, annotatedHandle);
if(!resRef)
ResourceReferenceInfo resRefInfo = GetResource(handleId, annotatedHandle);
if(!resRefInfo.Valid())
break;

BindingSlot binding(resRef->resourceBase.regBase + bindIndex.arrayElement,
resRef->resourceBase.space);
ShaderVariable arg;
RDCASSERT(GetShaderVariable(inst.args[2], opCode, dxOpCode, arg));
const char *opString = ToStr(dxOpCode).c_str();
ShaderVariable data = apiWrapper->GetSampleInfo(resRef->resourceBase.resClass, binding,
ShaderVariable data = apiWrapper->GetSampleInfo(resRefInfo.resClass, resRefInfo.binding,
m_ShaderType, opString);

uint32_t sampleCount = data.value.u32v[0];
Expand Down Expand Up @@ -1802,14 +1830,12 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
case DXOp::TextureGatherCmp:
{
Id handleId = GetArgumentId(1);
ShaderBindIndex bindIndex;
bool annotatedHandle;
const DXIL::ResourceReference *resRef = GetResource(handleId, bindIndex, annotatedHandle);
if(!resRef)
ResourceReferenceInfo resRefInfo = GetResource(handleId, annotatedHandle);
if(!resRefInfo.Valid())
break;

PerformGPUResourceOp(workgroups, opCode, dxOpCode, resRef, bindIndex, apiWrapper, inst,
result);
PerformGPUResourceOp(workgroups, opCode, dxOpCode, resRefInfo, apiWrapper, inst, result);
eventFlags |= ShaderEvents::SampleLoadGather;
break;
}
Expand All @@ -1828,17 +1854,16 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
// RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment)
const Id handleId = GetArgumentId(1);
bool annotatedHandle;
ShaderBindIndex bindIndex;
const DXIL::ResourceReference *resRef = GetResource(handleId, bindIndex, annotatedHandle);
if(!resRef)
ResourceReferenceInfo resRefInfo = GetResource(handleId, annotatedHandle);
if(!resRefInfo.Valid())
break;

ResourceClass resClass = resRef->resourceBase.resClass;
ResourceClass resClass = resRefInfo.resClass;
// SRV TextureLoad is done on the GPU
if((dxOpCode == DXOp::TextureLoad) && (resClass == ResourceClass::SRV))
{
PerformGPUResourceOp(workgroups, opCode, dxOpCode, resRef, bindIndex, apiWrapper,
inst, result);
PerformGPUResourceOp(workgroups, opCode, dxOpCode, resRefInfo, apiWrapper, inst,
result);
eventFlags |= ShaderEvents::SampleLoadGather;
break;
}
Expand Down Expand Up @@ -1887,18 +1912,17 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
uint32_t numElems = 0;
GlobalState::ViewFmt fmt;

BindingSlot resourceBinding(resRef->resourceBase.regBase, resRef->resourceBase.space);
RDCASSERT((resClass == ResourceClass::SRV || resClass == ResourceClass::UAV), resClass);
GlobalState::ResourceInfo resInfo;
switch(resClass)
{
case ResourceClass::UAV:
{
GlobalState::UAVIterator uavIter = m_GlobalState.uavs.find(resourceBinding);
GlobalState::UAVIterator uavIter = m_GlobalState.uavs.find(resRefInfo.binding);
if(uavIter == m_GlobalState.uavs.end())
{
apiWrapper->FetchUAV(resourceBinding);
uavIter = m_GlobalState.uavs.find(resourceBinding);
apiWrapper->FetchUAV(resRefInfo.binding);
uavIter = m_GlobalState.uavs.find(resRefInfo.binding);
}
const GlobalState::UAVData &uav = uavIter->second;
resInfo = uav.resInfo;
Expand All @@ -1911,11 +1935,11 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
}
case ResourceClass::SRV:
{
GlobalState::SRVIterator srvIter = m_GlobalState.srvs.find(resourceBinding);
GlobalState::SRVIterator srvIter = m_GlobalState.srvs.find(resRefInfo.binding);
if(srvIter == m_GlobalState.srvs.end())
{
apiWrapper->FetchSRV(resourceBinding);
srvIter = m_GlobalState.srvs.find(resourceBinding);
apiWrapper->FetchSRV(resRefInfo.binding);
srvIter = m_GlobalState.srvs.find(resRefInfo.binding);
}
const GlobalState::SRVData &srv = srvIter->second;
resInfo = srv.resInfo;
Expand Down Expand Up @@ -4530,9 +4554,9 @@ void ThreadState::UpdateMemoryVariableFromBackingMemory(Id memoryId, const void
}

void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups, Operation opCode,
DXOp dxOpCode, const DXIL::ResourceReference *resRef,
const ShaderBindIndex &bindIndex, DebugAPIWrapper *apiWrapper,
const DXIL::Instruction &inst, ShaderVariable &result)
DXOp dxOpCode, const ResourceReferenceInfo &resRefInfo,
DebugAPIWrapper *apiWrapper, const DXIL::Instruction &inst,
ShaderVariable &result)
{
// TextureLoad(srv,mipLevelOrSampleCount,coord0,coord1,coord2,offset0,offset1,offset2)
// Sample(srv,sampler,coord0,coord1,coord2,coord3,offset0,offset1,offset2,clamp)
Expand All @@ -4558,20 +4582,17 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
result.columns = (uint8_t)(retType->members.size() - 1);

// CalculateSampleGather is only valid for SRV resources
ResourceClass resClass = resRef->resourceBase.resClass;
ResourceClass resClass = resRefInfo.resClass;
RDCASSERTEQUAL(resClass, ResourceClass::SRV);

// resRef->resourceBase must be an SRV
const DXIL::EntryPointInterface::SRV &srv = resRef->resourceBase.srvData;
// Resource reference must be an SRV
const ResourceReferenceInfo::SRVData &srv = resRefInfo.srvData;

SampleGatherResourceData resourceData;
resourceData.dim = (DXDebug::ResourceDimension)ConvertResourceKindToResourceDimension(srv.shape);
resourceData.retType =
(DXDebug::ResourceRetType)ConvertComponentTypeToResourceRetType(srv.compType);
resourceData.dim = srv.dim;
resourceData.retType = srv.compType;
resourceData.sampleCount = srv.sampleCount;

resourceData.binding.registerSpace = resRef->resourceBase.space;
resourceData.binding.shaderRegister = resRef->resourceBase.regBase + bindIndex.arrayElement;
resourceData.binding = resRefInfo.binding;

ShaderVariable uv;
int8_t texelOffsets[3] = {0, 0, 0};
Expand All @@ -4594,13 +4615,23 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
uint32_t mipLevelOrSampleCount = arg.value.u32v[0];
// The debug shader uses arrays of resources for 1D, 2D textures
// mipLevel goes into UV[N] : N = 1D: 2, 2D: 3, 3D: 3
switch(srv.shape)
switch(srv.dim)
{
case DXIL::ResourceKind::Texture1D: uv.value.u32v[2] = mipLevelOrSampleCount; break;
case DXIL::ResourceKind::Texture2D: uv.value.u32v[3] = mipLevelOrSampleCount; break;
case DXIL::ResourceKind::Texture3D: uv.value.u32v[3] = mipLevelOrSampleCount; break;
case DXIL::ResourceKind::Texture2DMS: msIndex = mipLevelOrSampleCount; break;
case DXIL::ResourceKind::Texture2DMSArray: msIndex = mipLevelOrSampleCount; break;
case DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE1D:
uv.value.u32v[2] = mipLevelOrSampleCount;
break;
case DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2D:
uv.value.u32v[3] = mipLevelOrSampleCount;
break;
case DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE3D:
uv.value.u32v[3] = mipLevelOrSampleCount;
break;
case DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2DMS:
msIndex = mipLevelOrSampleCount;
break;
case DXBCBytecode::ResourceDimension::RESOURCE_DIMENSION_TEXTURE2DMSARRAY:
msIndex = mipLevelOrSampleCount;
break;
default: break;
}
}
Expand All @@ -4619,21 +4650,17 @@ void ThreadState::PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups,
{
// Sampler is in arg 2
Id samplerId = GetArgumentId(2);
ShaderBindIndex samplerBindIndex;
bool annotatedHandle;
const DXIL::ResourceReference *samplerRef =
GetResource(samplerId, samplerBindIndex, annotatedHandle);
if(!samplerRef)
ResourceReferenceInfo samplerRef = GetResource(samplerId, annotatedHandle);
if(!samplerRef.Valid())
return;

RDCASSERTEQUAL(samplerRef->resourceBase.resClass, ResourceClass::Sampler);
RDCASSERTEQUAL(samplerRef.resClass, ResourceClass::Sampler);
// samplerRef->resourceBase must be a Sampler
const DXIL::EntryPointInterface::Sampler &sampler = samplerRef->resourceBase.samplerData;
const ResourceReferenceInfo::SamplerData &sampler = samplerRef.samplerData;
samplerData.bias = 0.0f;
samplerData.binding.registerSpace = samplerRef->resourceBase.space;
samplerData.binding.shaderRegister =
samplerRef->resourceBase.regBase + samplerBindIndex.arrayElement;
samplerData.mode = ConvertSamplerKindToSamplerMode(sampler.samplerType);
samplerData.binding = samplerRef.binding;
samplerData.mode = sampler.samplerMode;

int32_t biasArg = -1;
int32_t lodArg = -1;
Expand Down Expand Up @@ -4816,28 +4843,31 @@ DXILDebug::Id ThreadState::GetArgumentId(uint32_t i) const
return GetSSAId(arg);
}

const DXIL::ResourceReference *ThreadState::GetResource(Id handleId, ShaderBindIndex &bindIndex,
bool &annotatedHandle)
ResourceReferenceInfo ThreadState::GetResource(Id handleId, bool &annotatedHandle)
{
ResourceReferenceInfo resRefInfo;
RDCASSERT(m_Live.contains(handleId));
auto it = m_Variables.find(handleId);
if(it != m_Variables.end())
{
const ShaderVariable &var = m_Variables.at(handleId);
const DXIL::ResourceReference *resRef = m_Program.GetResourceReference(handleId);
ShaderBindIndex bindIndex = var.GetBindIndex();
annotatedHandle = IsAnnotatedHandle(var);
RDCASSERT(!annotatedHandle || (m_AnnotatedProperties.count(handleId) == 1));
const DXIL::ResourceReference *resRef = NULL;
rdcstr alias = var.name;
resRef = m_Program.GetResourceReference(handleId);
if(resRef)
{
rdcstr alias = m_Program.GetHandleAlias(resRef->handleID);
bindIndex = var.GetBindIndex();
annotatedHandle = IsAnnotatedHandle(var);
RDCASSERT(!annotatedHandle || (m_AnnotatedProperties.count(handleId) == 1));
MarkResourceAccess(alias, bindIndex);
return resRef;
alias = m_Program.GetHandleAlias(resRef->handleID);
resRefInfo.Create(resRef, bindIndex.arrayElement);
}
MarkResourceAccess(alias, bindIndex);
return resRefInfo;
}

RDCERR("Unknown resource handle %u", handleId);
return NULL;
return resRefInfo;
}

void ThreadState::Sub(const ShaderVariable &a, const ShaderVariable &b, ShaderValue &ret) const
Expand Down
35 changes: 30 additions & 5 deletions renderdoc/driver/shaders/dxil/dxil_debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,32 @@ struct GlobalVariable
ShaderVariable var;
};

struct ResourceReferenceInfo
{
ResourceReferenceInfo() : resClass(DXIL::ResourceClass::Invalid) {}
void Create(const DXIL::ResourceReference *resRef, uint32_t arrayIndex);
bool Valid() const { return resClass != DXIL::ResourceClass::Invalid; }

DXIL::ResourceClass resClass;
BindingSlot binding;

struct SRVData
{
DXDebug::ResourceDimension dim;
uint32_t sampleCount;
DXDebug::ResourceRetType compType;
};
struct SamplerData
{
SamplerMode samplerMode;
};
union
{
SRVData srvData;
SamplerData samplerData;
};
};

class DebugAPIWrapper
{
public:
Expand Down Expand Up @@ -178,8 +204,7 @@ struct ThreadState
ShaderEvents flags);
rdcstr GetArgumentName(uint32_t i) const;
Id GetArgumentId(uint32_t i) const;
const DXIL::ResourceReference *GetResource(Id handleId, ShaderBindIndex &bindIndex,
bool &annotatedHandle);
ResourceReferenceInfo GetResource(Id handleId, bool &annotatedHandle);

bool GetShaderVariable(const DXIL::Value *dxilValue, DXIL::Operation op, DXIL::DXOp dxOpCode,
ShaderVariable &var, bool flushDenormInput = true) const
Expand All @@ -202,9 +227,9 @@ struct ThreadState
void UpdateMemoryVariableFromBackingMemory(Id memoryId, const void *ptr);

void PerformGPUResourceOp(const rdcarray<ThreadState> &workgroups, DXIL::Operation opCode,
DXIL::DXOp dxOpCode, const DXIL::ResourceReference *resRef,
const ShaderBindIndex &bindIndex, DebugAPIWrapper *apiWrapper,
const DXIL::Instruction &inst, ShaderVariable &result);
DXIL::DXOp dxOpCode, const ResourceReferenceInfo &resRef,
DebugAPIWrapper *apiWrapper, const DXIL::Instruction &inst,
ShaderVariable &result);
void Sub(const ShaderVariable &a, const ShaderVariable &b, ShaderValue &ret) const;

ShaderValue DDX(bool fine, DXIL::Operation opCode, DXIL::DXOp dxOpCode,
Expand Down

0 comments on commit aa548b3

Please sign in to comment.