diff options
| author | Yong He <yonghe@outlook.com> | 2024-03-12 13:47:14 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-12 13:47:14 -0700 |
| commit | edc85fc4631782d42e113f00dfbbd113dcd8c96f (patch) | |
| tree | 8d6ce10d7ea4d62633d9ce74d78ae2d41578fffb /source/slang | |
| parent | 8b5196033ae5e8113e6d06cb64c7cbe570496c51 (diff) | |
Make type names spec-conformant in SPIRV reflect. (#3748)
* Preserve ByteAddressBuffer user type name.
* Make user type lowercase.
* Make typenames conform to spec.
* Use `SpvOpDecorateString`.
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/slang-emit-spirv-ops.h | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 20 | ||||
| -rw-r--r-- | source/slang/slang-emit.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-byte-address-legalize.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-ir-lower-append-consume-structured-buffer.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-ir-spirv-legalize.cpp | 15 | ||||
| -rw-r--r-- | source/slang/slang-ir-user-type-hint.cpp | 34 | ||||
| -rw-r--r-- | source/slang/slang-ir-user-type-hint.h | 7 |
9 files changed, 75 insertions, 21 deletions
diff --git a/source/slang/slang-emit-spirv-ops.h b/source/slang/slang-emit-spirv-ops.h index f8c96bb30..42aeb8316 100644 --- a/source/slang/slang-emit-spirv-ops.h +++ b/source/slang/slang-emit-spirv-ops.h @@ -733,7 +733,7 @@ SpvInst* emitOpMemberDecorateString( ) { static_assert(isSingular<T>); - return emitInst(parent, inst, SpvOpMemberDecorate, target, index, decoration, text); + return emitInst(parent, inst, SpvOpMemberDecorateString, target, index, decoration, text); } // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpDecorate @@ -747,7 +747,7 @@ SpvInst* emitOpDecorateString( ) { static_assert(isSingular<T>); - return emitInst(parent, inst, SpvOpDecorate, target, decoration, text); + return emitInst(parent, inst, SpvOpDecorateString, target, decoration, text); } // https://registry.khronos.org/SPIR-V/specs/unified1/SPIRV.html#OpDecorate diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 252f0e917..79f324988 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -2919,6 +2919,24 @@ struct SPIRVEmitContext } } + // Make user type name conform to `SPV_GOOGLE_user_type` spec. + // https://github.com/KhronosGroup/SPIRV-Registry/blob/main/extensions/GOOGLE/SPV_GOOGLE_user_type.asciidoc + String legalizeUserTypeName(UnownedStringSlice typeName) + { + String result = typeName; + auto index = typeName.indexOf('<'); + if (index == -1) + index = typeName.getLength(); + StringBuilder sb; + sb << String(typeName.head(index)).toLower(); + if (index != typeName.getLength()) + { + sb << ":"; + sb << typeName.tail(index); + } + return sb.produceString(); + } + /// Emit an appropriate SPIR-V decoration for the given IR `decoration`, if necessary and possible. /// /// The given `dstID` should be the `<id>` of the SPIR-V instruction being decorated, @@ -3246,7 +3264,7 @@ struct SPIRVEmitContext decoration, dstID, SpvDecorationUserTypeGOOGLE, - cast<IRUserTypeNameDecoration>(decoration)->getUserTypeName()->getStringSlice()); + legalizeUserTypeName(cast<IRUserTypeNameDecoration>(decoration)->getUserTypeName()->getStringSlice()).getUnownedSlice()); } break; case kIROp_CounterBufferDecoration: diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 0ec9b0c1a..43f54d04f 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -32,6 +32,7 @@ #include "slang-ir-legalize-varying-params.h" #include "slang-ir-link.h" #include "slang-ir-com-interface.h" +#include "slang-ir-user-type-hint.h" #include "slang-ir-lower-append-consume-structured-buffer.h" #include "slang-ir-lower-binding-query.h" #include "slang-ir-lower-generics.h" @@ -537,6 +538,8 @@ Result linkAndOptimizeIR( lowerAppendConsumeStructuredBuffers(targetProgram, irModule, sink); } + addUserTypeHintDecorations(irModule); + // We don't need the legalize pass for C/C++ based types if(options.shouldLegalizeExistentialAndResourceTypes ) { diff --git a/source/slang/slang-ir-byte-address-legalize.cpp b/source/slang/slang-ir-byte-address-legalize.cpp index c1e22c89f..d5fc7ed5c 100644 --- a/source/slang/slang-ir-byte-address-legalize.cpp +++ b/source/slang/slang-ir-byte-address-legalize.cpp @@ -759,6 +759,8 @@ struct ByteAddressBufferLegalizationContext auto structuredBufferParam = paramBuilder.createGlobalParam(structuredBufferParamType); if (auto nameHint = byteAddressBufferParam->findDecoration<IRNameHintDecoration>()) paramBuilder.addNameHintDecoration(structuredBufferParam, nameHint->getName()); + if (auto typeHint = byteAddressBufferParam->findDecoration<IRUserTypeNameDecoration>()) + paramBuilder.addUserTypeNameDecoration(structuredBufferParam, typeHint->getUserTypeName()); // The new parameter needs to be given a layout to match the existing // parameter, so that it is given the same `binding` in the generated code. diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 0a7f8c33b..195bf577c 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -4287,6 +4287,11 @@ public: addNameHintDecoration(value, getStringValue(text)); } + void addUserTypeNameDecoration(IRInst* value, IRStringLit* name) + { + addDecoration(value, kIROp_UserTypeNameDecoration, name); + } + void addBinaryInterfaceTypeDecoration(IRInst* value) { addDecoration(value, kIROp_BinaryInterfaceTypeDecoration); diff --git a/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp b/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp index 6fb1e3140..da6b8d34d 100644 --- a/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp +++ b/source/slang/slang-ir-lower-append-consume-structured-buffer.cpp @@ -18,11 +18,11 @@ namespace Slang auto structType = builder.createStructType(); StringBuilder nameSb; if (type->getOp() == kIROp_HLSLAppendStructuredBufferType) - nameSb << "AppendStructuredBuffer_"; + nameSb << "AppendStructuredBuffer<"; else - nameSb << "ConsumeStructuredBuffer_"; + nameSb << "ConsumeStructuredBuffer<"; getTypeNameHint(nameSb, elementType); - nameSb << "_t"; + nameSb << ">"; builder.addNameHintDecoration(structType, nameSb.produceString().getUnownedSlice()); auto elementBufferKey = builder.createStructKey(); diff --git a/source/slang/slang-ir-spirv-legalize.cpp b/source/slang/slang-ir-spirv-legalize.cpp index b387a67f6..d072e2da0 100644 --- a/source/slang/slang-ir-spirv-legalize.cpp +++ b/source/slang/slang-ir-spirv-legalize.cpp @@ -496,21 +496,6 @@ struct SPIRVLegalizationContext : public SourceEmitterBase void processGlobalParam(IRGlobalParam* inst) { - if (inst->getDataType()) - { - // Preserve the original type name as a decoration before we do any type lowering. - // This is needed to implement -fspv-reflect, which allows the compiler to output the - // original user-friendly type name of each shader parameter as a SPIRV decoration. - // - StringBuilder sb; - getTypeNameHint(sb, inst->getDataType()); - if (sb.getLength()) - { - IRBuilder builder(inst); - builder.addDecoration(inst, kIROp_UserTypeNameDecoration, builder.getStringValue(sb.produceString().getUnownedSlice())); - } - } - // If the param is a texture, infer its format. if (auto textureType = as<IRTextureTypeBase>(unwrapArray(inst->getDataType()))) { diff --git a/source/slang/slang-ir-user-type-hint.cpp b/source/slang/slang-ir-user-type-hint.cpp new file mode 100644 index 000000000..3003d56f6 --- /dev/null +++ b/source/slang/slang-ir-user-type-hint.cpp @@ -0,0 +1,34 @@ +#include "slang-ir-user-type-hint.h" + +#include "slang-ir.h" +#include "slang-ir-insts.h" +#include "slang-ir-util.h" + +namespace Slang +{ + +void addUserTypeHintDecorations(IRModule* module) +{ + for (auto globalInst : module->getGlobalInsts()) + { + auto inst = as<IRGlobalParam>(globalInst); + if (!inst) + continue; + if (inst->getDataType()) + { + // Preserve the original type name as a decoration before we do any type lowering. + // This is needed to implement -fspv-reflect, which allows the compiler to output the + // original user-friendly type name of each shader parameter as a SPIRV decoration. + // + StringBuilder sb; + getTypeNameHint(sb, inst->getDataType()); + if (sb.getLength()) + { + IRBuilder builder(inst); + builder.addDecoration(inst, kIROp_UserTypeNameDecoration, builder.getStringValue(sb.produceString().getUnownedSlice())); + } + } + } +} + +} diff --git a/source/slang/slang-ir-user-type-hint.h b/source/slang/slang-ir-user-type-hint.h new file mode 100644 index 000000000..2fbfbd5e0 --- /dev/null +++ b/source/slang/slang-ir-user-type-hint.h @@ -0,0 +1,7 @@ +#pragma once + +namespace Slang +{ + struct IRModule; + void addUserTypeHintDecorations(IRModule* module); +} |
