Skip to content

Commit 58a6c44

Browse files
committed
PIX: Account for alignment when computing member offset (#4903)
* Account for alignment * Use llvm::RoundUpToAlignment
1 parent 83f8c6c commit 58a6c44

2 files changed

Lines changed: 134 additions & 13 deletions

File tree

lib/DxilDia/DxilDiaSymbolManager.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/IR/Intrinsics.h"
2929
#include "llvm/IR/Module.h"
3030
#include "llvm/Support/raw_ostream.h"
31+
#include "llvm/Support/MathExtras.h"
3132

3233
#include "DxilDiaSession.h"
3334
#include "DxilDiaTableSymbols.h"
@@ -596,10 +597,11 @@ class SymbolManagerInit {
596597
TypeInfo(const TypeInfo &) = delete;
597598
TypeInfo(TypeInfo &&) = default;
598599

599-
explicit TypeInfo(DWORD dwTypeID) : m_dwTypeID(dwTypeID) {}
600+
TypeInfo(DWORD dwTypeID, uint64_t alignInBits) : m_dwTypeID(dwTypeID), m_alignInBytes(alignInBits / 8) {}
600601

601602
DWORD GetTypeID() const { return m_dwTypeID; }
602603
DWORD GetCurrentSizeInBytes() const { return m_dwCurrentSizeInBytes; }
604+
uint64_t GetAlignmentInBytes() const { return m_alignInBytes; }
603605
const std::vector<llvm::DIType *> &GetLayout() const { return m_Layout; }
604606

605607
void Embed(const TypeInfo &TI);
@@ -610,6 +612,7 @@ class SymbolManagerInit {
610612
DWORD m_dwTypeID;
611613
std::vector<llvm::DIType *> m_Layout;
612614
DWORD m_dwCurrentSizeInBytes = 0;
615+
uint64_t m_alignInBytes;
613616
};
614617
using TypeToInfoMap = llvm::DenseMap<llvm::DIType *, std::unique_ptr<TypeInfo> >;
615618

@@ -662,9 +665,9 @@ class SymbolManagerInit {
662665
HRESULT GetTypeInfo(llvm::DIType *T, TypeInfo **TI);
663666

664667
template<typename Factory, typename... Args>
665-
HRESULT AddType(DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, Args&&... args) {
668+
HRESULT AddType(DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, uint64_t alignment, Args&&... args) {
666669
IFR(AddSymbol<Factory>(dwParentID, pNewSymID, std::forward<Args>(args)...));
667-
if (!m_TypeToInfo.insert(std::make_pair(T, llvm::make_unique<TypeInfo>(*pNewSymID))).second) {
670+
if (!m_TypeToInfo.insert(std::make_pair(T, llvm::make_unique<TypeInfo>(*pNewSymID, alignment))).second) {
668671
return E_FAIL;
669672
}
670673
return S_OK;
@@ -1140,13 +1143,22 @@ void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::Embed(const TypeInfo &
11401143
for (const auto &E : TI.GetLayout()) {
11411144
m_Layout.emplace_back(E);
11421145
}
1146+
uint64_t alignmentInBytes = TI.GetAlignmentInBytes();
1147+
if (alignmentInBytes != 0) {
1148+
m_dwCurrentSizeInBytes =
1149+
llvm::RoundUpToAlignment(m_dwCurrentSizeInBytes, alignmentInBytes);
1150+
}
11431151
m_dwCurrentSizeInBytes += TI.m_dwCurrentSizeInBytes;
11441152
}
11451153

11461154
void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::AddBasicType(llvm::DIBasicType *BT) {
11471155
m_Layout.emplace_back(BT);
11481156

11491157
static constexpr DWORD kNumBitsPerByte = 8;
1158+
uint64_t alignmentInBytes = BT->getAlignInBits() / kNumBitsPerByte;
1159+
if (alignmentInBytes != 0) {
1160+
m_dwCurrentSizeInBytes = llvm::RoundUpToAlignment(m_dwCurrentSizeInBytes, alignmentInBytes);
1161+
}
11501162
m_dwCurrentSizeInBytes += BT->getSizeInBits() / kNumBitsPerByte;
11511163
}
11521164

@@ -1402,7 +1414,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateSubroutineType(DWORD dw
14021414
};
14031415
}
14041416

1405-
IFR(AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, SymTagFunctionType, ST, LazyName));
1417+
IFR(AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, 0 /*alignment*/, SymTagFunctionType, ST, LazyName));
14061418

14071419
return S_OK;
14081420
}
@@ -1418,7 +1430,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateBasicType(DWORD dwParen
14181430
return S_OK;
14191431
};
14201432

1421-
IFR(AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, SymTagBaseType, BT, LazyName));
1433+
IFR(AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, BT->getAlignInBits(), SymTagBaseType, BT, LazyName));
14221434

14231435
TypeInfo *TI;
14241436
IFR(GetTypeInfo(BT, &TI));
@@ -1477,7 +1489,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwP
14771489
return S_OK;
14781490
};
14791491

1480-
IFR(AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, SymTagArrayType, CT, LazyName));
1492+
IFR(AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, BaseType->getAlignInBits(), SymTagArrayType, CT, LazyName));
14811493
TypeInfo *ctTI;
14821494
IFR(GetTypeInfo(CT, &ctTI));
14831495
TypeInfo *baseTI;
@@ -1512,7 +1524,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwP
15121524
return S_OK;
15131525
};
15141526

1515-
IFR(AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT, LazyName));
1527+
IFR(AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT->getAlignInBits(), CT, LazyName));
15161528

15171529
TypeInfo *udtTI;
15181530
IFR(GetTypeInfo(CT, &udtTI));
@@ -1612,7 +1624,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLVectorType(llvm::DI
16121624
}
16131625

16141626
const DWORD dwParentID = HlslProgramId;
1615-
IFR(AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T, dwElemTyID, ElemCnt->getLimitedValue()));
1627+
IFR(AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T->getAlignInBits(), T, dwElemTyID, ElemCnt->getLimitedValue()));
16161628

16171629
TypeInfo *vecTI;
16181630
IFR(GetTypeInfo(T, &vecTI));
@@ -1676,7 +1688,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwPar
16761688
return E_FAIL;
16771689
}
16781690

1679-
IFR(AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, DT, dwBaseTypeID));
1691+
IFR(AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, BaseTy->getAlignInBits(), DT, dwBaseTypeID));
16801692

16811693
TypeInfo *dtTI;
16821694
IFR(GetTypeInfo(DT, &dtTI));
@@ -1715,7 +1727,7 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwPar
17151727
}
17161728
}
17171729

1718-
IFR(AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, st, DT, LazyName));
1730+
IFR(AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, DT->getAlignInBits(), st, DT, LazyName));
17191731

17201732
if (DT->getTag() == llvm::dwarf::DW_TAG_const_type) {
17211733
TypeInfo *dtTI;
@@ -1788,13 +1800,16 @@ HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateUDTField(DWORD dwParent
17881800
DWORD dwLVTypeID;
17891801
IFR(CreateType(FieldTy, &dwLVTypeID));
17901802
if (m_pCurUDT != nullptr) {
1791-
const DWORD dwOffsetInBytes = CurrentUDTInfo().GetCurrentSizeInBytes();
1803+
TypeInfo *lvTI;
1804+
IFR(GetTypeInfo(FieldTy, &lvTI));
1805+
const DWORD dwOffsetInBytes =
1806+
(lvTI->GetAlignmentInBytes() == 0)
1807+
? CurrentUDTInfo().GetCurrentSizeInBytes()
1808+
: llvm::RoundUpToAlignment(CurrentUDTInfo().GetCurrentSizeInBytes(), lvTI->GetAlignmentInBytes());
17921809
DXASSERT_ARGS(dwOffsetInBytes == Field->getOffsetInBits() / 8,
17931810
"%d vs %d",
17941811
dwOffsetInBytes,
17951812
Field->getOffsetInBits() / 8);
1796-
TypeInfo *lvTI;
1797-
IFR(GetTypeInfo(FieldTy, &lvTI));
17981813
CurrentUDTInfo().Embed(*lvTI);
17991814
}
18001815

tools/clang/unittests/HLSL/PixTest.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ class PixTest {
227227
TEST_METHOD(RootSignatureUpgrade_SubObjects)
228228
TEST_METHOD(RootSignatureUpgrade_Annotation)
229229

230+
TEST_METHOD(SymbolManager_Embedded2DArray)
231+
230232
dxc::DxcDllSupport m_dllSupport;
231233
VersionSupportInfo m_ver;
232234

@@ -3603,4 +3605,108 @@ float4 main(int i : A, float j : B) : SV_TARGET
36033605
VERIFY_IS_TRUE(foundGlobalRS);
36043606
}
36053607

3608+
static CComPtr<IDxcBlob> GetDebugPart(dxc::DxcDllSupport &dllSupport,
3609+
IDxcBlob *container) {
3610+
3611+
CComPtr<IDxcLibrary> pLib;
3612+
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib));
3613+
CComPtr<IDxcContainerReflection> pReflection;
3614+
3615+
VERIFY_SUCCEEDED(
3616+
dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection));
3617+
VERIFY_SUCCEEDED(pReflection->Load(container));
3618+
3619+
UINT32 index;
3620+
VERIFY_SUCCEEDED(
3621+
pReflection->FindFirstPartKind(hlsl::DFCC_ShaderDebugInfoDXIL, &index));
3622+
3623+
CComPtr<IDxcBlob> debugPart;
3624+
VERIFY_SUCCEEDED(pReflection->GetPartContent(index, &debugPart));
3625+
3626+
return debugPart;
3627+
}
3628+
3629+
3630+
TEST_F(PixTest, SymbolManager_Embedded2DArray) {
3631+
const char *code = R"x(
3632+
struct EmbeddedStruct
3633+
{
3634+
uint32_t TwoDArray[2][2];
3635+
};
3636+
3637+
struct smallPayload
3638+
{
3639+
uint32_t OneInt;
3640+
EmbeddedStruct embeddedStruct;
3641+
uint64_t bigOne;
3642+
};
3643+
3644+
[numthreads(1, 1, 1)]
3645+
void ASMain()
3646+
{
3647+
smallPayload p;
3648+
p.OneInt = -137;
3649+
p.embeddedStruct.TwoDArray[0][0] = 252;
3650+
p.embeddedStruct.TwoDArray[0][1] = 253;
3651+
p.embeddedStruct.TwoDArray[1][0] = 254;
3652+
p.embeddedStruct.TwoDArray[1][1] = 255;
3653+
p.bigOne = 123456789;
3654+
3655+
DispatchMesh(2, 1, 1, p);
3656+
}
3657+
3658+
)x";
3659+
3660+
auto compiled = Compile(code, L"as_6_5", {}, L"ASMain");
3661+
3662+
auto debugPart = GetDebugPart(m_dllSupport, compiled);
3663+
3664+
CComPtr<IDxcLibrary> library;
3665+
VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
3666+
3667+
CComPtr<IStream> programStream;
3668+
VERIFY_SUCCEEDED(
3669+
library->CreateStreamFromBlobReadOnly(debugPart, &programStream));
3670+
3671+
CComPtr<IDiaDataSource> diaDataSource;
3672+
VERIFY_SUCCEEDED(
3673+
m_dllSupport.CreateInstance(CLSID_DxcDiaDataSource, &diaDataSource));
3674+
3675+
VERIFY_SUCCEEDED(diaDataSource->loadDataFromIStream(programStream));
3676+
3677+
CComPtr<IDiaSession> session;
3678+
VERIFY_SUCCEEDED(diaDataSource->openSession(&session));
3679+
3680+
CComPtr<IDxcPixDxilDebugInfoFactory> Factory;
3681+
VERIFY_SUCCEEDED(session->QueryInterface(&Factory));
3682+
CComPtr<IDxcPixDxilDebugInfo> dxilDebugger;
3683+
VERIFY_SUCCEEDED(Factory->NewDxcPixDxilDebugInfo(&dxilDebugger));
3684+
CComPtr<IDxcPixDxilLiveVariables> liveVariables;
3685+
VERIFY_SUCCEEDED(dxilDebugger->GetLiveVariablesAt(43, &liveVariables));
3686+
CComPtr<IDxcPixVariable> variable;
3687+
VERIFY_SUCCEEDED(liveVariables->GetVariableByIndex(0, &variable));
3688+
CComBSTR name;
3689+
variable->GetName(&name);
3690+
VERIFY_ARE_EQUAL_WSTR(name, L"p");
3691+
CComPtr<IDxcPixType> type;
3692+
VERIFY_SUCCEEDED(variable->GetType(&type));
3693+
CComPtr<IDxcPixStructType> structType;
3694+
VERIFY_SUCCEEDED(type->QueryInterface(IID_PPV_ARGS(&structType)));
3695+
auto ValidateStructMember = [&structType](DWORD index, const wchar_t *name,
3696+
uint64_t offset) {
3697+
CComPtr<IDxcPixStructField> member;
3698+
VERIFY_SUCCEEDED(structType->GetFieldByIndex(index, &member));
3699+
CComBSTR actualName;
3700+
VERIFY_SUCCEEDED(member->GetName(&actualName));
3701+
VERIFY_ARE_EQUAL_WSTR(actualName, name);
3702+
DWORD actualOffset= 0;
3703+
VERIFY_SUCCEEDED(member->GetOffsetInBits(&actualOffset));
3704+
VERIFY_ARE_EQUAL(actualOffset, offset);
3705+
};
3706+
3707+
ValidateStructMember(0, L"OneInt", 0);
3708+
ValidateStructMember(1, L"embeddedStruct", 4*8);
3709+
ValidateStructMember(2, L"bigOne", 24*8);
3710+
}
3711+
36063712
#endif

0 commit comments

Comments
 (0)