mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-11-14 01:41:10 +00:00
DXIL Debugger refactor resource access to use DXIL metadata
Remove use of DXBC Reflection from DXIL Debugger
This commit is contained in:
1 parent
eab144bd3f
commit
642a9954f4
6 files changed
+192
-244
No files matched your search
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user