DXIL Debugger refactor resource access to use DXIL metadata

Remove use of DXBC Reflection from DXIL Debugger
This commit is contained in:
Jake Turner committed 2024-11-28 17:33:26 +00:00
1 parent eab144bd3f
commit 642a9954f4
6 files changed
+192 -244

No files matched your search

+99 -123
View File
@@ -60,79 +60,60 @@ static bool IsShaderParameterVisible(DXBC::ShaderType shaderType,
return false;
}
static void FillViewFmt(DXGI_FORMAT format, GlobalState::ViewFmt &viewFmt)
static void FillViewFmtFromResourceFormat(DXGI_FORMAT format, GlobalState::ViewFmt &viewFmt)
{
if(format != DXGI_FORMAT_UNKNOWN)
{
ResourceFormat fmt = MakeResourceFormat(format);
RDCASSERT(format != DXGI_FORMAT_UNKNOWN);
ResourceFormat fmt = MakeResourceFormat(format);
viewFmt.byteWidth = fmt.compByteWidth;
viewFmt.numComps = fmt.compCount;
viewFmt.fmt = fmt.compType;
viewFmt.byteWidth = fmt.compByteWidth;
viewFmt.numComps = fmt.compCount;
viewFmt.compType = fmt.compType;
if(format == DXGI_FORMAT_R11G11B10_FLOAT)
viewFmt.byteWidth = 11;
else if(format == DXGI_FORMAT_R10G10B10A2_UINT || format == DXGI_FORMAT_R10G10B10A2_UNORM)
viewFmt.byteWidth = 10;
}
if(format == DXGI_FORMAT_R11G11B10_FLOAT)
viewFmt.byteWidth = 11;
else if(format == DXGI_FORMAT_R10G10B10A2_UINT || format == DXGI_FORMAT_R10G10B10A2_UNORM)
viewFmt.byteWidth = 10;
if(viewFmt.byteWidth == 10 || viewFmt.byteWidth == 11)
viewFmt.stride = 4; // 10 10 10 2 or 11 11 10
else
viewFmt.stride = viewFmt.byteWidth * viewFmt.numComps;
}
static void LookupUAVFormatFromShaderReflection(const DXBC::Reflection &reflection,
const BindingSlot &slot,
GlobalState::ViewFmt &viewFmt)
// Only valid/used fo root descriptors
// Root descriptors only have RawBuffer and StructuredBuffer types
static uint32_t GetUAVBufferStrideFromShaderMetadata(const DXIL::EntryPointInterface *reflection,
const BindingSlot &slot)
{
for(const DXBC::ShaderInputBind &bind : reflection.UAVs)
for(const DXIL::EntryPointInterface::ResourceBase &bind : reflection->uavs)
{
if(bind.reg == slot.shaderRegister && bind.space == slot.registerSpace &&
bind.dimension == DXBC::ShaderInputBind::DIM_BUFFER &&
bind.retType < DXBC::RETURN_TYPE_MIXED && bind.retType != DXBC::RETURN_TYPE_UNKNOWN)
if(bind.MatchesBinding(slot.shaderRegister, slot.shaderRegister, slot.registerSpace))
{
viewFmt.byteWidth = 4;
viewFmt.numComps = bind.numComps;
if(bind.retType == DXBC::RETURN_TYPE_UNORM)
viewFmt.fmt = CompType::UNorm;
else if(bind.retType == DXBC::RETURN_TYPE_SNORM)
viewFmt.fmt = CompType::SNorm;
else if(bind.retType == DXBC::RETURN_TYPE_UINT)
viewFmt.fmt = CompType::UInt;
else if(bind.retType == DXBC::RETURN_TYPE_SINT)
viewFmt.fmt = CompType::SInt;
else
viewFmt.fmt = CompType::Float;
break;
if(bind.uavData.shape == ResourceKind::RawBuffer ||
bind.uavData.shape == ResourceKind::StructuredBuffer)
{
return bind.uavData.elementStride;
}
}
}
return 0;
}
static void LookupSRVFormatFromShaderReflection(const DXBC::Reflection &reflection,
const BindingSlot &slot,
GlobalState::ViewFmt &viewFmt)
static uint32_t GetSRVBufferStrideFromShaderMetadata(const DXIL::EntryPointInterface *reflection,
const BindingSlot &slot)
{
for(const DXBC::ShaderInputBind &bind : reflection.SRVs)
for(const DXIL::EntryPointInterface::ResourceBase &bind : reflection->srvs)
{
if(bind.reg == slot.shaderRegister && bind.space == slot.registerSpace &&
bind.dimension == DXBC::ShaderInputBind::DIM_BUFFER &&
bind.retType < DXBC::RETURN_TYPE_MIXED && bind.retType != DXBC::RETURN_TYPE_UNKNOWN)
if(bind.MatchesBinding(slot.shaderRegister, slot.shaderRegister, slot.registerSpace))
{
viewFmt.byteWidth = 4;
viewFmt.numComps = bind.numComps;
if(bind.retType == DXBC::RETURN_TYPE_UNORM)
viewFmt.fmt = CompType::UNorm;
else if(bind.retType == DXBC::RETURN_TYPE_SNORM)
viewFmt.fmt = CompType::SNorm;
else if(bind.retType == DXBC::RETURN_TYPE_UINT)
viewFmt.fmt = CompType::UInt;
else if(bind.retType == DXBC::RETURN_TYPE_SINT)
viewFmt.fmt = CompType::SInt;
else
viewFmt.fmt = CompType::Float;
break;
if(bind.srvData.shape == ResourceKind::RawBuffer ||
bind.srvData.shape == ResourceKind::StructuredBuffer)
{
return bind.srvData.elementStride;
}
}
}
return 0;
}
static void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset,
@@ -150,9 +131,8 @@ static void FlattenSingleVariable(const rdcstr &cbufferName, uint32_t byteOffset
if(outvars[outIdx].columns > 0)
{
// if we already have a variable in this slot, just copy the data for this variable and add the
// source mapping.
// We should not overlap into the next register as that's not allowed.
// if we already have a variable in this slot, just copy the data for this variable and add
// the source mapping. We should not overlap into the next register as that's not allowed.
memcpy(&outvars[outIdx].value.u32v[outComp], &v.value.u32v[0], sizeof(uint32_t) * v.columns);
SourceVariableMapping mapping;
@@ -507,13 +487,12 @@ void GetInterpolationModeForInputParams(const rdcarray<SigParameter> &inputSig,
}
}
D3D12APIWrapper::D3D12APIWrapper(WrappedID3D12Device *device,
const DXBC::DXBCContainer *dxbcContainer, GlobalState &globalState,
uint32_t eventId)
D3D12APIWrapper::D3D12APIWrapper(WrappedID3D12Device *device, const DXIL::Program &dxilProgram,
GlobalState &globalState, uint32_t eventId)
: m_Device(device),
m_DXBC(dxbcContainer),
m_EntryPointInterface(dxilProgram.GetEntryPointInterface()),
m_GlobalState(globalState),
m_ShaderType(dxbcContainer->m_Type),
m_ShaderType(dxilProgram.GetShaderType()),
m_EventId(eventId)
{
}
@@ -574,32 +553,31 @@ void D3D12APIWrapper::FetchSRV(const BindingSlot &slot)
{
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
// DXBC allows root buffers to have a stride of up to 16 bytes in the shader, which
// means encoding the byte offset into the first element here is wrong without knowing
// what the actual accessed stride is. Instead we only fetch the data from that offset
// onwards.
// DXC allows root buffers to have a stride of up to 16 bytes in the shader, which
// means encoding the byte offset into the first element here is wrong without
// knowing what the actual accessed stride is. Instead we only fetch the data from
// that offset onwards.
// Root buffers are typeless, try with the resource desc format
// The debugger code will handle DXGI_FORMAT_UNKNOWN
if(resDesc.Format == DXGI_FORMAT_UNKNOWN)
{
// If we didn't get a format from the resource, try to pull it from the
// shader reflection info
DXILDebug::LookupSRVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot,
srvData.format);
}
else
{
DXILDebug::FillViewFmt(resDesc.Format, srvData.format);
}
srvData.firstElement = 0;
// root arguments have no bounds checking, so use the most conservative number of
// elements
srvData.numElements = uint32_t(resDesc.Width - element.offset);
if(resDesc.Format != DXGI_FORMAT_UNKNOWN)
DXILDebug::FillViewFmtFromResourceFormat(resDesc.Format, srvData.resInfo.format);
srvData.resInfo.isRootDescriptor = true;
srvData.resInfo.firstElement = 0;
// root arguments have no bounds checking, so use the most conservative number of elements
srvData.resInfo.numElements = uint32_t(resDesc.Width - element.offset);
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetSRVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
srvData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, element.offset, 0,
srvData.data);
}
}
return;
}
@@ -658,26 +636,26 @@ void D3D12APIWrapper::FetchSRV(const BindingSlot &slot)
if(srvDesc.Format != DXGI_FORMAT_UNKNOWN)
{
DXILDebug::FillViewFmt(srvDesc.Format, srvData.format);
DXILDebug::FillViewFmtFromResourceFormat(srvDesc.Format, srvData.resInfo.format);
}
else
{
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
srvData.format.stride = srvDesc.Buffer.StructureByteStride;
// If we didn't get a type from the SRV description, try to pull it from the
// shader reflection info
DXILDebug::LookupSRVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot,
srvData.format);
}
srvData.resInfo.format.stride = srvDesc.Buffer.StructureByteStride;
}
if(srvDesc.ViewDimension == D3D12_SRV_DIMENSION_BUFFER)
{
srvData.firstElement = (uint32_t)srvDesc.Buffer.FirstElement;
srvData.numElements = srvDesc.Buffer.NumElements;
srvData.resInfo.firstElement = (uint32_t)srvDesc.Buffer.FirstElement;
srvData.resInfo.numElements = srvDesc.Buffer.NumElements;
srvData.resInfo.isByteBuffer =
((srvDesc.Buffer.Flags & D3D12_BUFFER_SRV_FLAG_RAW) != 0) ? true : false;
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetSRVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
srvData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, 0, 0, srvData.data);
}
@@ -853,31 +831,33 @@ void D3D12APIWrapper::FetchUAV(const BindingSlot &slot)
if(pResource)
{
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
// DXBC allows root buffers to have a stride of up to 16 bytes in the shader, which
// means encoding the byte offset into the first element here is wrong without knowing
// what the actual accessed stride is. Instead we only fetch the data from that offset
// onwards.
// DXC allows root buffers to have a stride of up to 16 bytes in the shader, which
// means encoding the byte offset into the first element here is wrong without
// knowing what the actual accessed stride is. Instead we only fetch the data from
// that offset onwards.
// Root buffers are typeless, try with the resource desc format
// The debugger code will handle DXGI_FORMAT_UNKNOWN
if(resDesc.Format == DXGI_FORMAT_UNKNOWN)
if(resDesc.Format != DXGI_FORMAT_UNKNOWN)
{
// If we didn't get a format from the resource, try to pull it from the
// shader reflection info
DXILDebug::LookupUAVFormatFromShaderReflection(*m_DXBC->GetReflection(), slot,
uavData.format);
DXILDebug::FillViewFmtFromResourceFormat(resDesc.Format, uavData.resInfo.format);
}
else
{
DXILDebug::FillViewFmt(resDesc.Format, uavData.format);
}
uavData.firstElement = 0;
uavData.resInfo.isRootDescriptor = true;
uavData.resInfo.firstElement = 0;
// root arguments have no bounds checking, use the most conservative number of elements
uavData.numElements = uint32_t(resDesc.Width - element.offset);
uavData.resInfo.numElements = uint32_t(resDesc.Width - element.offset);
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetUAVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
uavData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, element.offset, 0,
uavData.data);
}
}
return;
@@ -941,23 +921,20 @@ void D3D12APIWrapper::FetchUAV(const BindingSlot &slot)
if(uavDesc.Format != DXGI_FORMAT_UNKNOWN)
{
DXILDebug::FillViewFmt(uavDesc.Format, uavData.format);
}
else
{
D3D12_RESOURCE_DESC resDesc = pResource->GetDesc();
if(resDesc.Dimension == D3D12_RESOURCE_DIMENSION_BUFFER)
{
uavData.format.stride = uavDesc.Buffer.StructureByteStride;
// TODO: Try looking up UAV from shader reflection info?
}
DXILDebug::FillViewFmtFromResourceFormat(uavDesc.Format, uavData.resInfo.format);
}
if(uavDesc.ViewDimension == D3D12_UAV_DIMENSION_BUFFER)
{
uavData.firstElement = (uint32_t)uavDesc.Buffer.FirstElement;
uavData.numElements = uavDesc.Buffer.NumElements;
uavData.resInfo.firstElement = (uint32_t)uavDesc.Buffer.FirstElement;
uavData.resInfo.numElements = uavDesc.Buffer.NumElements;
uavData.resInfo.isByteBuffer =
((uavDesc.Buffer.Flags & D3D12_BUFFER_UAV_FLAG_RAW) != 0) ? true : false;
// Get the buffer stride from the shader metadata (for StructuredBuffer, RawBuffer)
uint32_t mdStride =
DXILDebug::GetUAVBufferStrideFromShaderMetadata(m_EntryPointInterface, slot);
if(mdStride != 0)
uavData.resInfo.format.stride = mdStride;
m_Device->GetDebugManager()->GetBufferData(pResource, 0, 0, uavData.data);
}
@@ -1225,5 +1202,4 @@ bool D3D12APIWrapper::IsResourceBound(DXIL::ResourceClass resClass, const DXDebu
}
return false;
}
};
+2 -2
View File
@@ -41,7 +41,7 @@ void FetchConstantBufferData(WrappedID3D12Device *device, const DXIL::Program *p
class D3D12APIWrapper : public DebugAPIWrapper
{
public:
D3D12APIWrapper(WrappedID3D12Device *device, const DXBC::DXBCContainer *dxbcContainer,
D3D12APIWrapper(WrappedID3D12Device *device, const DXIL::Program &dxilProgram,
GlobalState &globalState, uint32_t eventId);
~D3D12APIWrapper();
@@ -67,7 +67,7 @@ private:
bool IsUAVBound(const BindingSlot &slot);
WrappedID3D12Device *m_Device;
const DXBC::DXBCContainer *m_DXBC;
const DXIL::EntryPointInterface *m_EntryPointInterface;
GlobalState &m_GlobalState;
DXBC::ShaderType m_ShaderType;
const uint32_t m_EventId;
+1 -1
View File
@@ -3393,7 +3393,7 @@ rdcarray<ShaderDebugState> D3D12Replay::ContinueDebug(ShaderDebugger *debugger)
if(((DXBCContainerDebugger *)debugger)->isDXIL)
{
DXILDebug::Debugger *dxilDebugger = (DXILDebug::Debugger *)debugger;
DXILDebug::D3D12APIWrapper apiWrapper(m_pDevice, dxilDebugger->GetDXBCContainer(),
DXILDebug::D3D12APIWrapper apiWrapper(m_pDevice, dxilDebugger->GetProgram(),
dxilDebugger->GetGlobalState(), dxilDebugger->GetEventId());
D3D12MarkerRegion region(m_pDevice->GetQueue()->GetReal(), "ContinueDebug Simulation Loop");
return dxilDebugger->ContinueDebug(&apiWrapper);
+62 -93
View File
@@ -875,14 +875,14 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S
{
uint32_t u = 0;
if(fmt.fmt == CompType::UInt)
if(fmt.compType == CompType::UInt)
{
u |= (value.u32v[0] & 0x3ff) << 0;
u |= (value.u32v[1] & 0x3ff) << 10;
u |= (value.u32v[2] & 0x3ff) << 20;
u |= (value.u32v[3] & 0x3) << 30;
}
else if(fmt.fmt == CompType::UNorm)
else if(fmt.compType == CompType::UNorm)
{
u = ConvertToR10G10B10A2(Vec4f(value.f32v[0], value.f32v[1], value.f32v[2], value.f32v[3]));
}
@@ -906,28 +906,28 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S
}
else if(fmt.byteWidth == 2)
{
if(fmt.fmt == CompType::Float)
if(fmt.compType == CompType::Float)
{
uint16_t *u = (uint16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
u[c] = ConvertToHalf(value.f32v[c]);
}
else if(fmt.fmt == CompType::UInt)
else if(fmt.compType == CompType::UInt)
{
uint16_t *u = (uint16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
u[c] = value.u32v[c] & 0xffff;
}
else if(fmt.fmt == CompType::SInt)
else if(fmt.compType == CompType::SInt)
{
int16_t *i = (int16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
i[c] = (int16_t)RDCCLAMP(value.s32v[c], (int32_t)INT16_MIN, (int32_t)INT16_MAX);
}
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB)
{
uint16_t *u = (uint16_t *)d;
@@ -937,7 +937,7 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S
u[c] = uint16_t(f);
}
}
else if(fmt.fmt == CompType::SNorm)
else if(fmt.compType == CompType::SNorm)
{
int16_t *i = (int16_t *)d;
@@ -958,21 +958,21 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S
}
else if(fmt.byteWidth == 1)
{
if(fmt.fmt == CompType::UInt)
if(fmt.compType == CompType::UInt)
{
uint8_t *u = (uint8_t *)d;
for(int c = 0; c < fmt.numComps; c++)
u[c] = value.u32v[c] & 0xff;
}
else if(fmt.fmt == CompType::SInt)
else if(fmt.compType == CompType::SInt)
{
int8_t *i = (int8_t *)d;
for(int c = 0; c < fmt.numComps; c++)
i[c] = (int8_t)RDCCLAMP(value.s32v[c], (int32_t)INT8_MIN, (int32_t)INT8_MAX);
}
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB)
{
uint8_t *u = (uint8_t *)d;
@@ -982,7 +982,7 @@ static void TypedUAVStore(DXILDebug::GlobalState::ViewFmt &fmt, byte *d, const S
u[c] = uint8_t(f);
}
}
else if(fmt.fmt == CompType::SNorm)
else if(fmt.compType == CompType::SNorm)
{
int8_t *i = (int8_t *)d;
@@ -1016,14 +1016,14 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte
uint32_t u;
memcpy(&u, d, sizeof(uint32_t));
if(fmt.fmt == CompType::UInt)
if(fmt.compType == CompType::UInt)
{
result.u32v[0] = (u >> 0) & 0x3ff;
result.u32v[1] = (u >> 10) & 0x3ff;
result.u32v[2] = (u >> 20) & 0x3ff;
result.u32v[3] = (u >> 30) & 0x003;
}
else if(fmt.fmt == CompType::UNorm)
else if(fmt.compType == CompType::UNorm)
{
Vec4f res = ConvertFromR10G10B10A2(u);
result.f32v[0] = res.x;
@@ -1058,35 +1058,35 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte
}
else if(fmt.byteWidth == 2)
{
if(fmt.fmt == CompType::Float)
if(fmt.compType == CompType::Float)
{
const uint16_t *u = (const uint16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.f32v[c] = ConvertFromHalf(u[c]);
}
else if(fmt.fmt == CompType::UInt)
else if(fmt.compType == CompType::UInt)
{
const uint16_t *u = (const uint16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.u32v[c] = u[c];
}
else if(fmt.fmt == CompType::SInt)
else if(fmt.compType == CompType::SInt)
{
const int16_t *in = (const int16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.s32v[c] = in[c];
}
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB)
{
const uint16_t *u = (const uint16_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.f32v[c] = float(u[c]) / float(0xffff);
}
else if(fmt.fmt == CompType::SNorm)
else if(fmt.compType == CompType::SNorm)
{
const int16_t *in = (const int16_t *)d;
@@ -1106,28 +1106,28 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte
}
else if(fmt.byteWidth == 1)
{
if(fmt.fmt == CompType::UInt)
if(fmt.compType == CompType::UInt)
{
const uint8_t *u = (const uint8_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.u32v[c] = u[c];
}
else if(fmt.fmt == CompType::SInt)
else if(fmt.compType == CompType::SInt)
{
const int8_t *in = (const int8_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.s32v[c] = in[c];
}
else if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB)
else if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB)
{
const uint8_t *u = (const uint8_t *)d;
for(int c = 0; c < fmt.numComps; c++)
result.f32v[c] = float(u[c]) / float(0xff);
}
else if(fmt.fmt == CompType::SNorm)
else if(fmt.compType == CompType::SNorm)
{
const int8_t *in = (const int8_t *)d;
@@ -1149,8 +1149,8 @@ static ShaderValue TypedUAVLoad(DXILDebug::GlobalState::ViewFmt &fmt, const byte
// fill in alpha with 1.0 or 1 as appropriate
if(fmt.numComps < 4)
{
if(fmt.fmt == CompType::UNorm || fmt.fmt == CompType::UNormSRGB ||
fmt.fmt == CompType::SNorm || fmt.fmt == CompType::Float)
if(fmt.compType == CompType::UNorm || fmt.compType == CompType::UNormSRGB ||
fmt.compType == CompType::SNorm || fmt.compType == CompType::Float)
result.f32v[3] = 1.0f;
else
result.u32v[3] = 1;
@@ -1186,7 +1186,7 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie
resType = resType->inner;
}
fmt.fmt = CompType::Typeless;
fmt.compType = CompType::Typeless;
if(resType->type == Type::Scalar)
{
fmt.numComps = compCount;
@@ -1195,12 +1195,12 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie
if(resType->scalarType == Type::ScalarKind::Int)
{
if(resType->bitWidth == 32)
fmt.fmt = CompType::SInt;
fmt.compType = CompType::SInt;
}
else if(resType->scalarType == Type::ScalarKind::Float)
{
if(resType->bitWidth == 32)
fmt.fmt = CompType::Float;
fmt.compType = CompType::Float;
}
}
else if(resType->type == Type::Struct)
@@ -1211,53 +1211,53 @@ void ConvertTypeToViewFormat(const DXIL::Type *type, DXILDebug::GlobalState::Vie
}
}
static void FillViewFmt(VarType type, DXILDebug::GlobalState::ViewFmt &fmt)
static void FillViewFmtFromVarType(VarType type, DXILDebug::GlobalState::ViewFmt &fmt)
{
switch(type)
{
case VarType::Float:
fmt.byteWidth = 4;
fmt.fmt = CompType::Float;
fmt.compType = CompType::Float;
break;
case VarType::Double:
fmt.byteWidth = 8;
fmt.fmt = CompType::Float;
fmt.compType = CompType::Float;
break;
case VarType::Half:
fmt.byteWidth = 2;
fmt.fmt = CompType::Float;
fmt.compType = CompType::Float;
break;
case VarType::SInt:
fmt.byteWidth = 4;
fmt.fmt = CompType::SInt;
fmt.compType = CompType::SInt;
break;
case VarType::UInt:
fmt.byteWidth = 4;
fmt.fmt = CompType::UInt;
fmt.compType = CompType::UInt;
break;
case VarType::SShort:
fmt.byteWidth = 2;
fmt.fmt = CompType::SInt;
fmt.compType = CompType::SInt;
break;
case VarType::UShort:
fmt.byteWidth = 2;
fmt.fmt = CompType::UInt;
fmt.compType = CompType::UInt;
break;
case VarType::SLong:
fmt.byteWidth = 8;
fmt.fmt = CompType::SInt;
fmt.compType = CompType::SInt;
break;
case VarType::ULong:
fmt.byteWidth = 2;
fmt.fmt = CompType::UInt;
fmt.compType = CompType::UInt;
break;
case VarType::SByte:
fmt.byteWidth = 1;
fmt.fmt = CompType::SInt;
fmt.compType = CompType::SInt;
break;
case VarType::UByte:
fmt.byteWidth = 1;
fmt.fmt = CompType::UInt;
fmt.compType = CompType::UInt;
break;
default: RDCERR("Unhandled Result Type %s", ToStr(type).c_str()); break;
}
@@ -1831,7 +1831,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
const bool raw = (dxOpCode == DXOp::RawBufferLoad) || (dxOpCode == DXOp::RawBufferStore);
const bool buffer = (dxOpCode == DXOp::BufferLoad) || (dxOpCode == DXOp::BufferStore) ||
(dxOpCode == DXOp::TextureLoad) || (dxOpCode == DXOp::TextureStore);
bool byteAddress = raw;
const bool load = (dxOpCode == DXOp::TextureLoad) || (dxOpCode == DXOp::BufferLoad) ||
(dxOpCode == DXOp::RawBufferLoad);
@@ -1864,21 +1863,6 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
}
uint32_t structOffset = 0;
uint32_t stride = 0;
if(buffer)
{
// Default for BufferLoad, BufferStore
// ByteAddressBuffer will have a stride of one
stride = 4;
}
else if(raw)
{
stride = 1;
}
RDCASSERT(stride != 0);
const byte *data = NULL;
size_t dataSize = 0;
bool texData = false;
@@ -1890,6 +1874,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
BindingSlot resourceBinding(resRef->resourceBase.regBase, resRef->resourceBase.space);
RDCASSERT((resClass == ResourceClass::SRV || resClass == ResourceClass::UAV), resClass);
GlobalState::ResourceInfo resInfo;
switch(resClass)
{
case ResourceClass::UAV:
@@ -1901,15 +1886,12 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
uavIter = m_GlobalState.uavs.find(resourceBinding);
}
const GlobalState::UAVData &uav = uavIter->second;
resInfo = uav.resInfo;
data = uav.data.data();
dataSize = uav.data.size();
texData = uav.tex;
rowPitch = uav.rowPitch;
depthPitch = uav.depthPitch;
firstElem = uav.firstElement;
numElems = uav.numElements;
fmt = uav.format;
stride = fmt.Stride();
break;
}
case ResourceClass::SRV:
@@ -1921,17 +1903,13 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
srvIter = m_GlobalState.srvs.find(resourceBinding);
}
const GlobalState::SRVData &srv = srvIter->second;
resInfo = srv.resInfo;
data = srv.data.data();
dataSize = srv.data.size();
firstElem = srv.firstElement;
numElems = srv.numElements;
fmt = srv.format;
stride = fmt.Stride();
break;
}
default: RDCERR("Unexpected ResourceClass %s", ToStr(resClass).c_str()); break;
}
// Unbound resource
if(data == NULL)
{
@@ -1945,32 +1923,23 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
break;
}
// Update the format if it is Typeless
// See FetchUAV() comment about root buffers being typeless
if(fmt.fmt == CompType::Typeless)
firstElem = resInfo.firstElement;
numElems = resInfo.numElements;
fmt = resInfo.format;
bool byteAddress = resInfo.isByteBuffer;
// If the format is unknown, guess it using the result type
// See FetchSRV(), FetchUAV() comment about root buffers being typeless
// The stride should have been computed from the shader metadata
if(fmt.compType == CompType::Typeless)
{
FillViewFmt(result.type, fmt);
FillViewFmtFromVarType(result.type, fmt);
fmt.numComps = result.columns;
if(fmt.stride == 0)
{
fmt.stride = 1;
stride = 1;
}
else
{
byteAddress = false;
stride = fmt.stride;
}
}
else
{
if(fmt.stride == 0)
fmt.stride = fmt.Stride();
stride = fmt.stride;
}
if(stride == 1)
byteAddress = true;
if(byteAddress)
fmt.stride = 1;
if(annotatedHandle)
{
@@ -1983,12 +1952,13 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
fmt.stride = props.structStride;
byteAddress = false;
}
stride = fmt.stride;
RDCASSERTNOTEQUAL(stride, 0);
}
uint32_t stride = fmt.stride;
RDCASSERT(!((stride == 1) ^ byteAddress));
RDCASSERTNOTEQUAL(stride, 0);
RDCASSERTNOTEQUAL(fmt.fmt, CompType::Typeless);
RDCASSERTNOTEQUAL(fmt.compType, CompType::Typeless);
uint32_t texCoords[3] = {0, 0, 0};
uint32_t elemIdx = 0;
@@ -2031,7 +2001,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
if(texData)
{
dataOffset += texCoords[0] * fmt.Stride();
dataOffset += texCoords[0] * stride;
dataOffset += texCoords[1] * rowPitch;
dataOffset += texCoords[2] * depthPitch;
}
@@ -2286,7 +2256,7 @@ bool ThreadState::ExecuteInstruction(DebugAPIWrapper *apiWrapper,
GlobalState::ViewFmt cbufferFmt;
cbufferFmt.byteWidth = byteWidth;
cbufferFmt.numComps = numComps;
cbufferFmt.fmt = CompType::Float;
cbufferFmt.compType = CompType::Float;
cbufferFmt.stride = 16;
result.value = TypedUAVLoad(cbufferFmt, data);
@@ -6044,8 +6014,7 @@ ShaderDebugTrace *Debugger::BeginDebug(uint32_t eventId, const DXBC::DXBCContain
{
ShaderStage shaderStage = reflection.stage;
m_DXBC = dxbcContainer;
m_Program = m_DXBC->GetDXILByteCode();
m_Program = dxbcContainer->GetDXILByteCode();
m_EventId = eventId;
m_ActiveLaneIndex = activeLaneIndex;
m_Steps = 0;
+20 -25
View File
@@ -292,50 +292,47 @@ struct GlobalState
{
int byteWidth = 0;
int numComps = 0;
CompType fmt = CompType::Typeless;
CompType compType = CompType::Typeless;
int stride = 0;
};
int Stride() const
struct ResourceInfo
{
ResourceInfo() : firstElement(0), numElements(0), isByteBuffer(false), isRootDescriptor(false)
{
if(stride != 0)
return stride;
if(byteWidth == 10 || byteWidth == 11)
return 4; // 10 10 10 2 or 11 11 10
return byteWidth * numComps;
}
uint32_t firstElement;
uint32_t numElements;
bool isByteBuffer;
bool isRootDescriptor;
// Buffer stride is stored in format.stride
ViewFmt format;
};
struct UAVData
{
UAVData()
: firstElement(0), numElements(0), tex(false), rowPitch(0), depthPitch(0), hiddenCounter(0)
{
}
UAVData() : tex(false), rowPitch(0), depthPitch(0), hiddenCounter(0) {}
ResourceInfo resInfo;
bytebuf data;
uint32_t firstElement;
uint32_t numElements;
bool tex;
uint32_t rowPitch, depthPitch;
ViewFmt format;
uint32_t hiddenCounter;
};
std::map<BindingSlot, UAVData> uavs;
typedef std::map<BindingSlot, UAVData>::const_iterator UAVIterator;
struct SRVData
{
SRVData() : firstElement(0), numElements(0) {}
bytebuf data;
uint32_t firstElement;
uint32_t numElements;
SRVData() {}
ViewFmt format;
ResourceInfo resInfo;
bytebuf data;
};
std::map<BindingSlot, SRVData> srvs;
@@ -467,7 +464,6 @@ public:
static rdcstr GetResourceReferenceName(const DXIL::Program *program, DXIL::ResourceClass resClass,
const BindingSlot &slot);
const DXIL::Program &GetProgram() const { return *m_Program; }
const DXBC::DXBCContainer *const GetDXBCContainer() { return m_DXBC; }
uint32_t GetEventId() { return m_EventId; }
const FunctionInfo *GetFunctionInfo(const DXIL::Function *function) const;
const rdcarray<DXIL::EntryPointInterface::Signature> &GetDXILEntryPointInputs(void) const
@@ -503,7 +499,6 @@ private:
std::map<const DXIL::Metadata *, TypeData> types;
} m_DebugInfo;
const DXBC::DXBCContainer *m_DXBC = NULL;
const DXIL::Program *m_Program = NULL;
const DXIL::Function *m_EntryPointFunction = NULL;
const DXIL::EntryPointInterface *m_EntryPointInterface = NULL;
@@ -306,6 +306,8 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con
SRV &srv = srvData;
srv.shape = getival<ResourceKind>(md->children[(size_t)ResField::SRVShape]);
srv.sampleCount = getival<uint32_t>(md->children[(size_t)ResField::SRVSampleCount]);
srv.compType = ComponentType::Invalid;
srv.elementStride = ~0U;
const Metadata *tags = md->children[(size_t)ResField::SRVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
@@ -332,6 +334,11 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con
uav.hasCounter = (getival<uint32_t>(md->children[(size_t)ResField::UAVHiddenCounter]) == 1);
uav.rasterizerOrderedView =
(getival<uint32_t>(md->children[(size_t)ResField::UAVRasterOrder]) == 1);
uav.compType = ComponentType::Invalid;
uav.elementStride = ~0U;
uav.samplerFeedback = SamplerFeedbackType::LastEntry;
uav.atomic64Use = false;
const Metadata *tags = md->children[(size_t)ResField::UAVTags];
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
@@ -360,6 +367,7 @@ EntryPointInterface::ResourceBase::ResourceBase(ResourceClass resourceClass, con
CBuffer &cbuffer = cbufferData;
cbuffer.sizeInBytes = getival<uint32_t>(md->children[(size_t)ResField::CBufferByteSize]);
const Metadata *tags = md->children[(size_t)ResField::CBufferTags];
cbuffer.isTBuffer = false;
for(size_t t = 0; tags && t < tags->children.size(); t += 2)
{
RDCASSERT(tags->children[t]->isConstant);