diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-emit.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-ir-legalize-types.cpp | 10 | ||||
| -rw-r--r-- | source/slang/slang-legalize-types.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-legalize-types.h | 2 |
4 files changed, 26 insertions, 1 deletions
diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index 841f44a80..8d7577b52 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -1278,6 +1278,15 @@ Result linkAndOptimizeIR( // legalizeResourceTypes(targetProgram, irModule, sink); + // We also need to legalize empty types for Metal targets. + switch (target) + { + case CodeGenTarget::Metal: + case CodeGenTarget::MetalLib: + case CodeGenTarget::MetalLibAssembly: + legalizeEmptyTypes(targetProgram, irModule, sink); + break; + } // Debugging output of legalization #if 0 dumpIRIfEnabled(codeGenContext, irModule, "LEGALIZED"); diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp index 197cd93c5..837193abc 100644 --- a/source/slang/slang-ir-legalize-types.cpp +++ b/source/slang/slang-ir-legalize-types.cpp @@ -4123,6 +4123,11 @@ struct IREmptyTypeLegalizationContext : IRTypeLegalizationContext bool isSimpleType(IRType* type) override { + if (isMetalTarget(targetProgram->getTargetReq())) + { + return false; + } + // If type is used as public interface, then treat it as simple. for (auto decor : type->getDecorations()) { @@ -4145,6 +4150,11 @@ struct IREmptyTypeLegalizationContext : IRTypeLegalizationContext { return LegalType(); } + + virtual bool shouldLegalizeParameterBlockElementType() override + { + return isMetalTarget(targetProgram->getTargetReq()); + } }; // The main entry points that are used when transforming IR code diff --git a/source/slang/slang-legalize-types.cpp b/source/slang/slang-legalize-types.cpp index e26475522..cc2c12d42 100644 --- a/source/slang/slang-legalize-types.cpp +++ b/source/slang/slang-legalize-types.cpp @@ -1211,11 +1211,15 @@ LegalType legalizeTypeImpl(TypeLegalizationContext* context, IRType* type) LegalType legalElementType; if (isMetalTarget(context->targetProgram->getTargetReq()) && - as<IRParameterBlockType>(uniformBufferType)) + as<IRParameterBlockType>(uniformBufferType) && + !context->shouldLegalizeParameterBlockElementType()) { // On Metal, we do not need to legalize the element type of // a parameter block because we can translate it directly into // an argument buffer. + // + // But we do need empty type legalized for Metal, because Metal doesn't + // allow empty struct in argument buffer. legalElementType = LegalType::simple(originalElementType); } else diff --git a/source/slang/slang-legalize-types.h b/source/slang/slang-legalize-types.h index ae76cbd39..f1b15877d 100644 --- a/source/slang/slang-legalize-types.h +++ b/source/slang/slang-legalize-types.h @@ -659,6 +659,8 @@ struct IRTypeLegalizationContext IROp op, LegalType legalElementType, IRInst* layoutOperand) = 0; + + virtual bool shouldLegalizeParameterBlockElementType() { return false; } }; // This typedef exists to support pre-existing code from when |
