Skip to content

Commit 7c2a4d0

Browse files
authored
Fix NS debug bool type in SSBO/UBO. (KhronosGroup#4061)
For GLSL, bool types inside of a buffer or uniform block are translated to uint in SPIR-V. However, the debug info should still represent the type as a bool. The fix is to construct a bool type in this special case and inject it into the makeMemberDebugType function. This is more complicated than it should be, because the make*DebugType functions treat their ID argument as a real SPIR-V OpType instea
1 parent 767dcb2 commit 7c2a4d0

File tree

6 files changed

+336
-18
lines changed

6 files changed

+336
-18
lines changed

SPIRV/GlslangToSpv.cpp

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5596,7 +5596,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
55965596
int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0,
55975597
// except sometimes for blocks
55985598
std::vector<std::pair<glslang::TType*, glslang::TQualifier> > deferredForwardPointers;
5599-
std::vector<spv::DebugTypeLoc> memberDebugInfo;
5599+
std::vector<spv::StructMemberDebugInfo> memberDebugInfo;
56005600
for (int i = 0; i < (int)glslangMembers->size(); i++) {
56015601
auto& glslangMember = (*glslangMembers)[i];
56025602
if (glslangMember.type->hiddenMember()) {
@@ -5647,11 +5647,33 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy
56475647
// + Not as clean as desired. Traverser queries/sets persistent state. This is fragile.
56485648
// + Table lookup during creation of composite debug types. This really shouldn't be necessary.
56495649
if(options.emitNonSemanticShaderDebugInfo) {
5650-
spv::DebugTypeLoc typeLoc{};
5651-
typeLoc.name = glslangMember.type->getFieldName().c_str();
5652-
typeLoc.line = glslangMember.loc.line;
5653-
typeLoc.column = glslangMember.loc.column;
5654-
memberDebugInfo.push_back(typeLoc);
5650+
spv::StructMemberDebugInfo debugInfo{};
5651+
debugInfo.name = glslangMember.type->getFieldName();
5652+
debugInfo.line = glslangMember.loc.line;
5653+
debugInfo.column = glslangMember.loc.column;
5654+
5655+
// Per the GLSL spec, bool variables inside of a uniform or buffer block are generated as uint.
5656+
// But for debug info, we want to represent them as bool because that is the original type in
5657+
// the source code. The bool type can be nested within a vector or a multidimensional array,
5658+
// so we must construct the chain of types up from the scalar bool.
5659+
if (glslangIntermediate->getSource() == glslang::EShSourceGlsl && explicitLayout != glslang::ElpNone &&
5660+
glslangMember.type->getBasicType() == glslang::EbtBool) {
5661+
auto typeId = builder.makeBoolType();
5662+
if (glslangMember.type->isVector()) {
5663+
typeId = builder.makeVectorType(typeId, glslangMember.type->getVectorSize());
5664+
}
5665+
if (glslangMember.type->isArray()) {
5666+
const auto* arraySizes = glslangMember.type->getArraySizes();
5667+
int dims = arraySizes->getNumDims();
5668+
for (int i = dims - 1; i >= 0; --i) {
5669+
spv::Id size = builder.makeIntConstant(arraySizes->getDimSize(i));
5670+
typeId = builder.makeArrayType(typeId, size, 0);
5671+
}
5672+
}
5673+
debugInfo.debugTypeOverride = builder.getDebugType(typeId);
5674+
}
5675+
5676+
memberDebugInfo.push_back(debugInfo);
56555677
}
56565678
}
56575679
}

SPIRV/SpvBuilder.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ Id Builder::makeFloatE4M3Type()
420420
// needed as the result of some instructions, which does
421421
// check for duplicates.
422422
// For compiler-generated structs, debug info is ignored.
423-
Id Builder::makeStructType(const std::vector<Id>& members, const std::vector<spv::DebugTypeLoc>& memberDebugInfo,
423+
Id Builder::makeStructType(const std::vector<Id>& members, const std::vector<spv::StructMemberDebugInfo>& memberDebugInfo,
424424
const char* name, bool const compilerGenerated)
425425
{
426426
// Don't look for previous one, because in the general case,
@@ -1156,7 +1156,7 @@ Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool
11561156
return type->getResultId();
11571157
}
11581158

1159-
Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc)
1159+
Id Builder::makeMemberDebugType(Id const memberType, StructMemberDebugInfo const& debugTypeLoc)
11601160
{
11611161
assert(debugId[memberType] != 0);
11621162

@@ -1165,12 +1165,13 @@ Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTy
11651165
type->addIdOperand(nonSemanticShaderDebugInfo);
11661166
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember);
11671167
type->addIdOperand(getStringId(debugTypeLoc.name)); // name id
1168-
type->addIdOperand(debugId[memberType]); // type id
1169-
type->addIdOperand(makeDebugSource(currentFileId)); // source id
1170-
type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero
1168+
type->addIdOperand(debugTypeLoc.debugTypeOverride != 0 ? debugTypeLoc.debugTypeOverride
1169+
: debugId[memberType]); // type id
1170+
type->addIdOperand(makeDebugSource(currentFileId)); // source id
1171+
type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero
11711172
type->addIdOperand(makeUintConstant(debugTypeLoc.column)); // TODO: column id
1172-
type->addIdOperand(makeUintConstant(0)); // TODO: offset id
1173-
type->addIdOperand(makeUintConstant(0)); // TODO: size id
1173+
type->addIdOperand(makeUintConstant(0)); // TODO: offset id
1174+
type->addIdOperand(makeUintConstant(0)); // TODO: size id
11741175
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); // flags id
11751176

11761177
groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMember].push_back(type);
@@ -1180,7 +1181,7 @@ Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTy
11801181
return type->getResultId();
11811182
}
11821183

1183-
Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vector<DebugTypeLoc> const& memberDebugInfo,
1184+
Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vector<StructMemberDebugInfo> const& memberDebugInfo,
11841185
char const* const name, NonSemanticShaderDebugInfo100DebugCompositeType const tag)
11851186
{
11861187
// Create the debug member types.

SPIRV/SpvBuilder.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,12 @@ typedef enum {
8282
Spv_1_6 = (1 << 16) | (6 << 8),
8383
} SpvVersion;
8484

85-
struct DebugTypeLoc {
85+
struct StructMemberDebugInfo {
8686
std::string name {};
8787
int line {0};
8888
int column {0};
89+
// Set if the caller knows a better debug type than what is associated with the functional SPIR-V type.
90+
spv::Id debugTypeOverride {0};
8991
};
9092

9193
class Builder {
@@ -204,6 +206,14 @@ class Builder {
204206
return id;
205207
}
206208

209+
// Maps the given OpType Id to a Non-Semantic DebugType Id.
210+
Id getDebugType(Id type) {
211+
if (emitNonSemanticShaderDebugInfo) {
212+
return debugId[type];
213+
}
214+
return 0;
215+
}
216+
207217
// For creating new types (will return old type if the requested one was already made).
208218
Id makeVoidType();
209219
Id makeBoolType();
@@ -217,7 +227,7 @@ class Builder {
217227
Id makeBFloat16Type();
218228
Id makeFloatE5M2Type();
219229
Id makeFloatE4M3Type();
220-
Id makeStructType(const std::vector<Id>& members, const std::vector<spv::DebugTypeLoc>& memberDebugInfo,
230+
Id makeStructType(const std::vector<Id>& members, const std::vector<spv::StructMemberDebugInfo>& memberDebugInfo,
221231
const char* name, bool const compilerGenerated = true);
222232
Id makeStructResultType(Id type0, Id type1);
223233
Id makeVectorType(Id component, int size);
@@ -244,8 +254,8 @@ class Builder {
244254
Id makeArrayDebugType(Id const baseType, Id const componentCount);
245255
Id makeVectorDebugType(Id const baseType, int const componentCount);
246256
Id makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor = true);
247-
Id makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc);
248-
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vector<DebugTypeLoc> const& memberDebugInfo,
257+
Id makeMemberDebugType(Id const memberType, StructMemberDebugInfo const& debugTypeLoc);
258+
Id makeCompositeDebugType(std::vector<Id> const& memberTypes, std::vector<StructMemberDebugInfo> const& memberDebugInfo,
249259
char const* const name, NonSemanticShaderDebugInfo100DebugCompositeType const tag);
250260
Id makeOpaqueDebugType(char const* const name);
251261
Id makePointerDebugType(StorageClass storageClass, Id const baseType);

0 commit comments

Comments
 (0)