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 | |
| 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`.
| -rw-r--r-- | build/visual-studio/slang/slang.vcxproj | 2 | ||||
| -rw-r--r-- | build/visual-studio/slang/slang.vcxproj.filters | 6 | ||||
| -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 | ||||
| -rw-r--r-- | tests/spirv/spirv-reflection.slang | 22 |
12 files changed, 95 insertions, 31 deletions
diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj index 6ca03e63a..9277df88f 100644 --- a/build/visual-studio/slang/slang.vcxproj +++ b/build/visual-studio/slang/slang.vcxproj @@ -472,6 +472,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla <ClInclude Include="..\..\..\source\slang\slang-ir-translate-glsl-global-var.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-uniformity.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-use-uninitialized-out-param.h" />
+ <ClInclude Include="..\..\..\source\slang\slang-ir-user-type-hint.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-util.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-validate.h" />
<ClInclude Include="..\..\..\source\slang\slang-ir-vk-invert-y.h" />
@@ -693,6 +694,7 @@ IF EXIST ..\..\..\external\slang-glslang\bin\windows-aarch64\release\slang-glsla <ClCompile Include="..\..\..\source\slang\slang-ir-translate-glsl-global-var.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-uniformity.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-use-uninitialized-out-param.cpp" />
+ <ClCompile Include="..\..\..\source\slang\slang-ir-user-type-hint.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-util.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-validate.cpp" />
<ClCompile Include="..\..\..\source\slang\slang-ir-vk-invert-y.cpp" />
diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters index eceb57b9f..a427febb5 100644 --- a/build/visual-studio/slang/slang.vcxproj.filters +++ b/build/visual-studio/slang/slang.vcxproj.filters @@ -504,6 +504,9 @@ <ClInclude Include="..\..\..\source\slang\slang-ir-use-uninitialized-out-param.h">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="..\..\..\source\slang\slang-ir-user-type-hint.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
<ClInclude Include="..\..\..\source\slang\slang-ir-util.h">
<Filter>Header Files</Filter>
</ClInclude>
@@ -1163,6 +1166,9 @@ <ClCompile Include="..\..\..\source\slang\slang-ir-use-uninitialized-out-param.cpp">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\..\..\source\slang\slang-ir-user-type-hint.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
<ClCompile Include="..\..\..\source\slang\slang-ir-util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
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); +} diff --git a/tests/spirv/spirv-reflection.slang b/tests/spirv/spirv-reflection.slang index 90414eb59..d1de9e974 100644 --- a/tests/spirv/spirv-reflection.slang +++ b/tests/spirv/spirv-reflection.slang @@ -9,25 +9,27 @@ struct MyElement } StructuredBuffer<MyElement> myBuffer : MY_HLSL_SEMANTIC1; AppendStructuredBuffer<float> myAppendBuffer : MY_HLSL_SEMANTIC2; - +ByteAddressBuffer bw; [numthreads(8, 8, 1)] void computeMain() { float4 color = mTexture.Load(int3(0, 0, 0)); - myAppendBuffer.Append(color.x + myBuffer[0].x); + myAppendBuffer.Append(color.x + myBuffer[0].x + bw.Load(0)); } // SPIRV-DAG: OpExtension "SPV_GOOGLE_user_type" -// SPIRV-DAG: OpDecorate %mTexture UserTypeGOOGLE "Texture2D" -// SPIRV-DAG: OpDecorate %mTexture UserSemantic "MY_HLSL_SEMANTIC" +// SPIRV-DAG: OpDecorateString %mTexture UserTypeGOOGLE "texture2d" +// SPIRV-DAG: OpDecorateString %mTexture UserSemantic "MY_HLSL_SEMANTIC" -// SPIRV-DAG: OpDecorate %myBuffer UserTypeGOOGLE "StructuredBuffer<MyElement_std430>" -// SPIRV-DAG: OpDecorate %myBuffer UserSemantic "MY_HLSL_SEMANTIC1" +// SPIRV-DAG: OpDecorateString %myBuffer UserTypeGOOGLE "structuredbuffer:<MyElement>" +// SPIRV-DAG: OpDecorateString %myBuffer UserSemantic "MY_HLSL_SEMANTIC1" -// SPIRV-DAG: OpDecorate %myAppendBuffer_counter UserTypeGOOGLE "RWStructuredBuffer<int>" -// SPIRV-DAG: OpDecorate %myAppendBuffer_counter UserSemantic "MY_HLSL_SEMANTIC2" +// SPIRV-DAG: OpDecorateString %myAppendBuffer_counter UserTypeGOOGLE "appendstructuredbuffer:<float>" +// SPIRV-DAG: OpDecorateString %myAppendBuffer_counter UserSemantic "MY_HLSL_SEMANTIC2" -// SPIRV-DAG: OpDecorate %myAppendBuffer_elements UserTypeGOOGLE "RWStructuredBuffer<float>" -// SPIRV-DAG: OpDecorate %myAppendBuffer_elements UserSemantic "MY_HLSL_SEMANTIC2" +// SPIRV-DAG: OpDecorateString %myAppendBuffer_elements UserTypeGOOGLE "appendstructuredbuffer:<float>" +// SPIRV-DAG: OpDecorateString %myAppendBuffer_elements UserSemantic "MY_HLSL_SEMANTIC2" // SPIRV-DAG: OpDecorateId %myAppendBuffer_elements CounterBuffer %myAppendBuffer_counter + +// SPIRV-DAG: OpDecorateString %bw UserTypeGOOGLE "byteaddressbuffer"
\ No newline at end of file |
