diff --git a/tools/clang/lib/SPIRV/DebugTypeVisitor.cpp b/tools/clang/lib/SPIRV/DebugTypeVisitor.cpp index 46d967bd73..d8b9bd6cc9 100644 --- a/tools/clang/lib/SPIRV/DebugTypeVisitor.cpp +++ b/tools/clang/lib/SPIRV/DebugTypeVisitor.cpp @@ -262,16 +262,16 @@ DebugTypeVisitor::lowerToDebugType(const SpirvType *spirvType) { auto *arrType = dyn_cast(spirvType); SpirvDebugInstruction *elemDebugType = lowerToDebugType(arrType->getElementType()); + + llvm::SmallVector counts; if (auto *dbgArrType = dyn_cast(elemDebugType)) { - auto &counts = dbgArrType->getElementCount(); - // Note that this is reverse order of dimension. We must iterate the - // count array in a reverse order when we actually emit it. - counts.push_back(arrType->getElementCount()); - debugType = dbgArrType; - } else { - debugType = spvContext.getDebugTypeArray(spirvType, elemDebugType, - {arrType->getElementCount()}); + counts.insert(counts.end(), dbgArrType->getElementCount().begin(), + dbgArrType->getElementCount().end()); + elemDebugType = dbgArrType->getElementType(); } + counts.push_back(arrType->getElementCount()); + + debugType = spvContext.getDebugTypeArray(spirvType, elemDebugType, counts); break; } case SpirvType::TK_Vector: { diff --git a/tools/clang/lib/SPIRV/EmitVisitor.cpp b/tools/clang/lib/SPIRV/EmitVisitor.cpp index 0618df71ed..a824c17560 100644 --- a/tools/clang/lib/SPIRV/EmitVisitor.cpp +++ b/tools/clang/lib/SPIRV/EmitVisitor.cpp @@ -1343,6 +1343,8 @@ bool EmitVisitor::visit(SpirvDebugTypeArray *inst) { curInst.push_back(inst->getDebugOpcode()); curInst.push_back( getOrAssignResultId(inst->getElementType())); + + // This is a reverse order of dimensions, thereby emitting in a reverse order. for (auto it = inst->getElementCount().rbegin(); it != inst->getElementCount().rend(); ++it) { const auto countId = typeHandler.getOrCreateConstantInt( @@ -1350,6 +1352,7 @@ bool EmitVisitor::visit(SpirvDebugTypeArray *inst) { /* isSpecConst */ false); curInst.push_back(countId); } + finalizeInstruction(&richDebugInfo); return true; } diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.type.array-from-same-type.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.type.array-from-same-type.hlsl new file mode 100644 index 0000000000..0184109a79 --- /dev/null +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.type.array-from-same-type.hlsl @@ -0,0 +1,25 @@ +// Run: %dxc -T ps_6_0 -E main -fspv-debug=rich + +struct UBO +{ + float4x4 a; + float4x4 b[3]; + float4 c; +}; + +cbuffer ubo : register(b0) { UBO ubo; } + +// CHECK: [[bName:%\d+]] = OpString "b" +// CHECK: [[aName:%\d+]] = OpString "a" +// CHECK: [[fooName:%\d+]] = OpString "foo" + +// CHECK: [[matf4v4_arr3:%\d+]] = OpExtInst %void [[ext:%\d+]] DebugTypeArray [[dbg_f:%\d+]] %uint_3 %uint_4 %uint_4 +// CHECK: OpExtInst %void [[ext]] DebugTypeMember [[bName]] [[matf4v4_arr3]] +// CHECK: [[matf4v4:%\d+]] = OpExtInst %void [[ext]] DebugTypeArray [[dbg_f]] %uint_4 %uint_4 +// CHECK: OpExtInst %void [[ext]] DebugTypeMember [[aName]] [[matf4v4]] +// CHECK: OpExtInst %void [[ext]] DebugLocalVariable [[fooName]] [[matf4v4]] + +void main() { + float4x4 foo = ubo.a; + foo += ubo.b[0] * ubo.c[0]; +} diff --git a/tools/clang/test/CodeGenSPIRV/rich.debug.type.array.hlsl b/tools/clang/test/CodeGenSPIRV/rich.debug.type.array.hlsl index fe146cbe01..255d392740 100644 --- a/tools/clang/test/CodeGenSPIRV/rich.debug.type.array.hlsl +++ b/tools/clang/test/CodeGenSPIRV/rich.debug.type.array.hlsl @@ -12,10 +12,10 @@ // CHECK: [[bool:%\d+]] = OpExtInst %void [[set]] DebugTypeBasic [[boolName]] %uint_32 Boolean // CHECK: [[int:%\d+]] = OpExtInst %void [[set]] DebugTypeBasic [[intName]] %uint_32 Signed // CHECK: [[uint:%\d+]] = OpExtInst %void [[set]] DebugTypeBasic [[uintName]] %uint_32 Unsigned +// CHECK: [[float:%\d+]] = OpExtInst %void [[set]] DebugTypeBasic [[floatName]] %uint_32 Float // CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugTypeArray [[S]] %uint_8 // CHECK: [[boolv4:%\d+]] = OpExtInst %void [[set]] DebugTypeVector [[bool]] 4 // CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugTypeArray [[boolv4]] %uint_7 -// CHECK: [[float:%\d+]] = OpExtInst %void [[set]] DebugTypeBasic [[floatName]] %uint_32 Float // CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugTypeArray [[float]] %uint_8 %uint_4 // CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugTypeArray [[int]] %uint_8 // CHECK: {{%\d+}} = OpExtInst %void [[set]] DebugTypeArray [[uint]] %uint_4 diff --git a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp index 4b199ae71d..8dab1b4551 100644 --- a/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp +++ b/tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp @@ -2317,6 +2317,10 @@ TEST_F(FileTest, RichDebugInfoTypeArray) { runFileTest("rich.debug.type.array.hlsl", Expect::Success, /*runValidation*/ runValidationForRichDebugInfo); } +TEST_F(FileTest, RichDebugInfoTypeArrayFromSameType) { + runFileTest("rich.debug.type.array-from-same-type.hlsl", Expect::Success, + /*runValidation*/ runValidationForRichDebugInfo); +} TEST_F(FileTest, RichDebugInfoTypeFunction) { runFileTest("rich.debug.type.function.hlsl", Expect::Success, /*runValidation*/ runValidationForRichDebugInfo);