diff options
| author | Yong He <yonghe@outlook.com> | 2024-06-08 02:16:41 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-08 02:16:41 -0700 |
| commit | 65928afe4f94e3c7e5fe33c1428f9d7afc14c7c5 (patch) | |
| tree | 8995b961a95802832fd2e5fdabab1148f5524ee5 /source | |
| parent | e39ceab5670184ad8b77f5b1aa4bb18b7ab231bc (diff) | |
Metal system value overhaul. (#4308)
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.cpp | 101 | ||||
| -rw-r--r-- | source/slang/slang-emit-metal.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-ir-inst-defs.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-ir-insts.h | 19 | ||||
| -rw-r--r-- | source/slang/slang-ir-metal-legalize.cpp | 327 |
6 files changed, 370 insertions, 85 deletions
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 4cf6a899d..b011227fd 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -828,8 +828,11 @@ DIAGNOSTIC(55102, Error, invalidTorchKernelParamType, "'$0' is not a valid param DIAGNOSTIC(55200, Error, unsupportedBuiltinType, "'$0' is not a supported builtin type for the target.") DIAGNOSTIC(55201, Error, unsupportedRecursion, "recursion detected in call to '$0', but the current code generation target does not allow recursion.") +DIAGNOSTIC(55202, Error, systemValueAttributeNotSupported, "system value semantic '$0' is not supported for the current target.") +DIAGNOSTIC(55203, Error, systemValueTypeIncompatible, "system value semantic '$0' should have type '$1' or convertible to type '$1'.") DIAGNOSTIC(56001, Error, unableToAutoMapCUDATypeToHostType, "Could not automatically map '$0' to a host type. Automatic binding generation failed for '$1'") + DIAGNOSTIC(57001, Warning, spirvOptFailed, "spirv-opt failed. $0") // GLSL Compatibility diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp index 96843e286..366c51840 100644 --- a/source/slang/slang-emit-metal.cpp +++ b/source/slang/slang-emit-metal.cpp @@ -170,8 +170,11 @@ void MetalSourceEmitter::emitFuncParamLayoutImpl(IRInst* param) break; } } - if (auto sysSemanticAttr = layout->findSystemValueSemanticAttr()) - _emitSystemSemantic(sysSemanticAttr->getName(), sysSemanticAttr->getIndex()); + if (!maybeEmitSystemSemantic(param)) + { + if (auto sysSemanticAttr = layout->findSystemValueSemanticAttr()) + _emitUserSemantic(sysSemanticAttr->getName(), sysSemanticAttr->getIndex()); + } } void MetalSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type) @@ -741,84 +744,24 @@ void MetalSourceEmitter::_emitType(IRType* type, DeclaratorInfo* declarator) } } -void MetalSourceEmitter::_emitSystemSemantic(UnownedStringSlice semanticName, IRIntegerValue semanticIndex) +bool MetalSourceEmitter::maybeEmitSystemSemantic(IRInst* inst) { - if (semanticName.caseInsensitiveEquals(toSlice("SV_POSITION"))) - { - m_writer->emit(" [[position]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_VERTEXID"))) - { - m_writer->emit(" [[vertex_id]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_INSTANCEID"))) - { - m_writer->emit(" [[instance_id]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_Target"))) - { - m_writer->emit(" [[color("); - m_writer->emit(semanticIndex); - m_writer->emit(")]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_PRIMITIVEID"))) + if (auto sysSemanticDecor = inst->findDecoration<IRTargetSystemValueDecoration>()) { - m_writer->emit(" [[primitive_id]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_GROUPID"))) - { - // TODO: not supported by metal. - // We need to implement the transformation logic in slang-ir-metal-legalize.cpp - // to convert SV_GroupID to something like METAL_threadgroup_position_in_grid. - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_GROUPINDEX"))) - { - // TODO: not supported by metal. - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_DISPATCHTHREADID"))) - { - m_writer->emit(" [[thread_position_in_grid]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_GROUPTHREADID"))) - { - m_writer->emit(" [[thread_position_in_threadgroup]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_CLIPDISTANCE"))) - { - m_writer->emit(" [[clip_distance]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_RENDERTARGETARRAYINDEX"))) - { - m_writer->emit(" [[render_target_array_index]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_VIEWPORTARRAYINDEX"))) - { - m_writer->emit(" [[viewport_array_index]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_Depth"))) - { - m_writer->emit(" [[depth(any)]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_DepthGreaterEqual"))) - { - m_writer->emit(" [[depth(greater)]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_DepthLessEqual"))) - { - m_writer->emit(" [[depth(less)]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_Coverage"))) - { - m_writer->emit(" [[sample_mask]]"); - } - else if (semanticName.caseInsensitiveEquals(toSlice("SV_StencilRef"))) - { - m_writer->emit(" [[stencil]]"); + m_writer->emit(" [["); + m_writer->emit(sysSemanticDecor->getSemantic()); + m_writer->emit("]]"); + return true; } - else + return false; +} + +void MetalSourceEmitter::_emitUserSemantic(UnownedStringSlice semanticName, IRIntegerValue semanticIndex) +{ + if (!semanticName.startsWithCaseInsensitive(toSlice("SV_"))) { m_writer->emit(" [[user("); - m_writer->emit(semanticName); + m_writer->emit(String(semanticName).toUpper()); if (semanticIndex != 0) { m_writer->emit("_"); @@ -834,6 +777,10 @@ void MetalSourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsets) if (inst->getOp() == kIROp_StructKey) { // Only emit [[attribute(n)]] on struct keys. + + if (maybeEmitSystemSemantic(inst)) + return; + bool hasSemanticFromLayout = false; if (auto varLayout = findVarLayout(inst)) { @@ -851,7 +798,7 @@ void MetalSourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsets) else if (auto semanticAttr = as<IRSemanticAttr>(attr)) { auto semanticName = String(semanticAttr->getName()).toUpper(); - _emitSystemSemantic(semanticAttr->getName(), semanticAttr->getIndex()); + _emitUserSemantic(semanticAttr->getName(), semanticAttr->getIndex()); hasSemanticFromLayout = true; } } @@ -861,7 +808,7 @@ void MetalSourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsets) { if (auto semanticDecor = inst->findDecoration<IRSemanticDecoration>()) { - _emitSystemSemantic(semanticDecor->getSemanticName(), semanticDecor->getSemanticIndex()); + _emitUserSemantic(semanticDecor->getSemanticName(), semanticDecor->getSemanticIndex()); } } } diff --git a/source/slang/slang-emit-metal.h b/source/slang/slang-emit-metal.h index 55ad3d4cb..8b014d604 100644 --- a/source/slang/slang-emit-metal.h +++ b/source/slang/slang-emit-metal.h @@ -76,7 +76,8 @@ protected: void _emitHLSLDecorationSingleInt(const char* name, IRFunc* entryPoint, IRIntLit* val); void _emitStageAccessSemantic(IRStageAccessDecoration* decoration, const char* name); - void _emitSystemSemantic(UnownedStringSlice semanticName, IRIntegerValue semanticIndex); + void _emitUserSemantic(UnownedStringSlice semanticName, IRIntegerValue semanticIndex); + bool maybeEmitSystemSemantic(IRInst* inst); }; } diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index 4d39eb978..37e3d2064 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -715,6 +715,8 @@ INST_RANGE(BindingQuery, GetRegisterIndex, GetRegisterSpace) INST_RANGE(TargetSpecificDecoration, TargetDecoration, RequirePreludeDecoration) INST(GLSLOuterArrayDecoration, glslOuterArray, 1, 0) + INST(TargetSystemValueDecoration, TargetSystemValue, 2, 0) + INST(InterpolationModeDecoration, interpolationMode, 1, 0) INST(NameHintDecoration, nameHint, 1, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 5670cad47..301604bf3 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -118,6 +118,19 @@ struct IRTargetDecoration : IRTargetSpecificDefinitionDecoration IR_LEAF_ISA(TargetDecoration) }; +struct IRTargetSystemValueDecoration : IRDecoration +{ + enum { kOp = kIROp_TargetSystemValueDecoration }; + IR_LEAF_ISA(TargetSystemValueDecoration) + + IRStringLit* getSemanticOperand() { return cast<IRStringLit>(getOperand(0)); } + + UnownedStringSlice getSemantic() + { + return getSemanticOperand()->getStringSlice(); + } +}; + struct IRTargetIntrinsicDecoration : IRTargetSpecificDefinitionDecoration { enum { kOp = kIROp_TargetIntrinsicDecoration }; @@ -4351,6 +4364,12 @@ public: void addHighLevelDeclDecoration(IRInst* value, Decl* decl); + IRDecoration* addTargetSystemValueDecoration(IRInst* value, UnownedStringSlice sysValName, UInt index = 0) + { + IRInst* operands[] = { getStringValue(sysValName), getIntValue(getIntType(), index)}; + return addDecoration(value, kIROp_TargetSystemValueDecoration, operands, SLANG_COUNT_OF(operands)); + } + // void addLayoutDecoration(IRInst* value, Layout* layout); void addLayoutDecoration(IRInst* value, IRLayout* layout); diff --git a/source/slang/slang-ir-metal-legalize.cpp b/source/slang/slang-ir-metal-legalize.cpp index d4a234515..70f4cbd27 100644 --- a/source/slang/slang-ir-metal-legalize.cpp +++ b/source/slang/slang-ir-metal-legalize.cpp @@ -50,6 +50,12 @@ namespace Slang auto structType = as<IRStructType>(param->getDataType()); builder.setInsertBefore(func->getFirstBlock()->getFirstOrdinaryInst()); auto varLayout = findVarLayout(param); + + // If `param` already has a semantic, we don't want to hoist its fields out. + if (varLayout->findSystemValueSemanticAttr() != nullptr || + param->findDecoration<IRSemanticDecoration>()) + continue; + IRStructTypeLayout* structTypeLayout = nullptr; if (varLayout) structTypeLayout = as<IRStructTypeLayout>(varLayout->getTypeLayout()); @@ -214,8 +220,168 @@ namespace Slang fixUpFuncType(func); } + struct MetalSystemValueInfo + { + String metalSystemValueName; + IRType* requiredType; + IRType* altRequiredType; + bool isUnsupported; + bool isSpecial; + }; - void ensureResultStructHasUserSemantic(IRStructType* structType, IRVarLayout* varLayout) + MetalSystemValueInfo getSystemValueInfo(IRBuilder& builder, String semanticName, UInt attrIndex) + { + SLANG_UNUSED(attrIndex); + + MetalSystemValueInfo result = {}; + + semanticName = semanticName.toLower(); + + if (semanticName == "sv_position") + { + result.metalSystemValueName = toSlice("position"); + result.requiredType = builder.getVectorType(builder.getBasicType(BaseType::Float), builder.getIntValue(builder.getIntType(), 4)); + } + else if (semanticName == "sv_clipdistance") + { + result.isSpecial = true; + } + else if (semanticName == "sv_culldistance") + { + result.isSpecial = true; + } + else if (semanticName == "sv_coverage") + { + result.metalSystemValueName = toSlice("sample_mask"); + result.requiredType = builder.getBasicType(BaseType::UInt); + } + else if (semanticName == "sv_innercoverage") + { + result.isSpecial = true; + + } + else if (semanticName == "sv_depth") + { + result.metalSystemValueName = toSlice("depth(any)"); + result.requiredType = builder.getBasicType(BaseType::Float); + } + else if (semanticName == "sv_depthgreaterequal") + { + result.metalSystemValueName = toSlice("depth(greater)"); + result.requiredType = builder.getBasicType(BaseType::Float); + } + else if (semanticName == "sv_depthlessequal") + { + result.metalSystemValueName = toSlice("depth(less)"); + result.requiredType = builder.getBasicType(BaseType::Float); + } + else if (semanticName == "sv_dispatchthreadid") + { + result.metalSystemValueName = toSlice("thread_position_in_grid"); + result.requiredType = builder.getVectorType(builder.getBasicType(BaseType::UInt), builder.getIntValue(builder.getIntType(), 3)); + } + else if (semanticName == "sv_domainlocation") + { + result.metalSystemValueName = toSlice("position_in_patch"); + result.requiredType = builder.getVectorType(builder.getBasicType(BaseType::Float), builder.getIntValue(builder.getIntType(), 3)); + result.altRequiredType = builder.getVectorType(builder.getBasicType(BaseType::Float), builder.getIntValue(builder.getIntType(), 2)); + } + else if (semanticName == "sv_groupid") + { + result.isSpecial = true; + } + else if (semanticName == "sv_groupindex") + { + result.isSpecial = true; + } + else if (semanticName == "sv_groupthreadid") + { + result.metalSystemValueName = toSlice("thread_position_in_threadgroup"); + result.requiredType = builder.getVectorType(builder.getBasicType(BaseType::UInt), builder.getIntValue(builder.getIntType(), 3)); + } + else if (semanticName == "sv_gsinstanceid") + { + // Metal does not have geometry shader, so this is invalid. + result.isUnsupported = true; + } + else if (semanticName == "sv_instanceid") + { + result.metalSystemValueName = toSlice("instance_id"); + result.requiredType = builder.getBasicType(BaseType::UInt); + } + else if (semanticName == "sv_isfrontface") + { + result.metalSystemValueName = toSlice("front_facing"); + result.requiredType = builder.getBasicType(BaseType::Bool); + } + else if (semanticName == "sv_outputcontrolpointid") + { + // In metal, a hull shader is just a compute shader. + // This needs to be handled separately, by lowering into an ordinary buffer. + } + else if (semanticName == "sv_pointsize") + { + result.metalSystemValueName = toSlice("point_size"); + result.requiredType = builder.getBasicType(BaseType::Float); + } + else if (semanticName == "sv_primitiveid") + { + result.metalSystemValueName = toSlice("patch_id"); + result.requiredType = builder.getBasicType(BaseType::UInt); + result.altRequiredType = builder.getBasicType(BaseType::UInt16); + } + else if (semanticName == "sv_rendertargetarrayindex") + { + result.metalSystemValueName = toSlice("render_target_array_index"); + result.requiredType = builder.getBasicType(BaseType::UInt); + result.altRequiredType = builder.getBasicType(BaseType::UInt16); + } + else if (semanticName == "sv_sampleindex") + { + result.metalSystemValueName = toSlice("sample_id"); + result.requiredType = builder.getBasicType(BaseType::UInt); + } + else if (semanticName == "sv_stencilref") + { + result.metalSystemValueName = toSlice("stencil"); + result.requiredType = builder.getBasicType(BaseType::UInt); + } + else if (semanticName == "sv_tessfactor") + { + // Tessellation factor outputs should be lowered into a write into a normal buffer. + } + else if (semanticName == "sv_vertexid") + { + result.metalSystemValueName = toSlice("vertex_id"); + result.requiredType = builder.getBasicType(BaseType::UInt); + } + else if (semanticName == "sv_viewid") + { + result.isUnsupported = true; + } + else if (semanticName == "sv_viewportarrayindex") + { + result.metalSystemValueName = toSlice("viewport_array_index"); + result.requiredType = builder.getBasicType(BaseType::UInt); + result.altRequiredType = builder.getBasicType(BaseType::UInt16); + } + else if (semanticName == "sv_target") + { + result.metalSystemValueName = (StringBuilder() << "color(" << String(attrIndex) << ")").produceString(); + } + else + { + result.isUnsupported = true; + } + return result; + } + + void reportUnsupportedSystemAttribute(DiagnosticSink* sink, IRInst* param, String semanticName) + { + sink->diagnose(param->sourceLoc, Diagnostics::systemValueAttributeNotSupported, semanticName); + } + + void ensureResultStructHasUserSemantic(DiagnosticSink* sink, IRStructType* structType, IRVarLayout* varLayout) { // Ensure each field in an output struct type has either a system semantic or a user semantic, // so that signature matching can happen correctly. @@ -225,8 +391,21 @@ namespace Slang for (auto field : structType->getFields()) { auto key = field->getKey(); - if (key->findDecoration<IRSemanticDecoration>()) + if (auto semanticDecor = key->findDecoration<IRSemanticDecoration>()) { + if (semanticDecor->getSemanticName().startsWithCaseInsensitive(toSlice("sv_"))) + { + auto sysValInfo = getSystemValueInfo(builder, semanticDecor->getSemanticName(), semanticDecor->getSemanticIndex()); + if (sysValInfo.isUnsupported || sysValInfo.isSpecial) + { + reportUnsupportedSystemAttribute(sink, field, semanticDecor->getSemanticName()); + } + else + { + builder.addTargetSystemValueDecoration(key, sysValInfo.metalSystemValueName.getUnownedSlice()); + semanticDecor->removeAndDeallocate(); + } + } index++; continue; } @@ -245,7 +424,7 @@ namespace Slang } - void wrapReturnValueInStruct(EntryPointInfo entryPoint) + void wrapReturnValueInStruct(DiagnosticSink* sink, EntryPointInfo entryPoint) { // Wrap return value into a struct if it is not already a struct. // For example, given this entry point: @@ -275,7 +454,7 @@ namespace Slang // If return type is already a struct, just make sure every field has a semantic. if (auto returnStructType = as<IRStructType>(returnType)) { - ensureResultStructHasUserSemantic(returnStructType, resultLayout); + ensureResultStructHasUserSemantic(sink, returnStructType, resultLayout); return; } @@ -288,13 +467,14 @@ namespace Slang auto key = builder.createStructKey(); builder.addNameHintDecoration(key, toSlice("output")); builder.addLayoutDecoration(key, resultLayout); + builder.addTargetSystemValueDecoration(key, toSlice("color(0)")); builder.createStructField(structType, key, returnType); IRStructTypeLayout::Builder structTypeLayoutBuilder(&builder); structTypeLayoutBuilder.addField(key, resultLayout); auto typeLayout = structTypeLayoutBuilder.build(); IRVarLayout::Builder varLayoutBuilder(&builder, typeLayout); auto varLayout = varLayoutBuilder.build(); - ensureResultStructHasUserSemantic(structType, varLayout); + ensureResultStructHasUserSemantic(sink, structType, varLayout); for (auto block : func->getBlocks()) { @@ -401,13 +581,146 @@ namespace Slang }); } - void legalizeEntryPointForMetal(EntryPointInfo entryPoint, DiagnosticSink* sink) + IRInst* tryConvertValue(IRBuilder& builder, IRInst* val, IRType* toType) + { + auto fromType = val->getFullType(); + if (auto fromVector = as<IRVectorType>(fromType)) + { + if (auto toVector = as<IRVectorType>(toType)) + { + if (fromVector->getElementCount() != toVector->getElementCount()) + { + fromType = builder.getVectorType(fromVector->getElementType(), toVector->getElementCount()); + val = builder.emitVectorReshape(fromType, val); + } + } + else if (as<IRBasicType>(toType)) + { + UInt index = 0; + val = builder.emitSwizzle(fromVector->getElementType(), val, 1, &index); + if (toType->getOp() == kIROp_VoidType) + return nullptr; + } + } + else if (auto fromBasicType = as<IRBasicType>(fromType)) + { + if (fromBasicType->getOp() == kIROp_VoidType) + return nullptr; + if (!as<IRBasicType>(toType)) + return nullptr; + if (toType->getOp() == kIROp_VoidType) + return nullptr; + } + else + { + return nullptr; + } + return builder.emitCast(toType, val); + } + + void legalizeSystemValueParameters(EntryPointInfo entryPoint, DiagnosticSink* sink) { SLANG_UNUSED(sink); + struct SystemValLegalizationWorkItem + { + IRParam* param; + String attrName; + UInt attrIndex; + }; + List<SystemValLegalizationWorkItem> systemValWorkItems; + List<SystemValLegalizationWorkItem> workList; + + IRBuilder builder(entryPoint.entryPointFunc); + List<IRParam*> params; + + for (auto param : entryPoint.entryPointFunc->getParams()) + { + if (auto semanticDecoration = param->findDecoration<IRSemanticDecoration>()) + { + if (semanticDecoration->getSemanticName().startsWithCaseInsensitive(toSlice("sv_"))) + { + systemValWorkItems.add({ param, String(semanticDecoration->getSemanticName()).toLower(), (UInt)semanticDecoration->getSemanticIndex() }); + continue; + } + } + + auto layoutDecor = param->findDecoration<IRLayoutDecoration>(); + if (!layoutDecor) + continue; + auto sysValAttr = layoutDecor->findAttr<IRSystemValueSemanticAttr>(); + if (!sysValAttr) + continue; + auto semanticName = String(sysValAttr->getName()); + auto sysAttrIndex = sysValAttr->getIndex(); + systemValWorkItems.add({ param, semanticName, sysAttrIndex }); + } + for (auto workItem : systemValWorkItems) + { + auto param = workItem.param; + auto semanticName = workItem.attrName; + auto sysAttrIndex = workItem.attrIndex; + + auto info = getSystemValueInfo(builder, semanticName, sysAttrIndex); + if (info.isSpecial) + { + if (semanticName == "sv_innercoverage") + { + // Metal does not support conservative rasterization, so this is always false. + auto val = builder.getBoolValue(false); + param->replaceUsesWith(val); + param->removeAndDeallocate(); + } + else + { + // Process special cases after trivial cases. + workList.add(workItem); + } + } + if (info.isUnsupported) + { + reportUnsupportedSystemAttribute(sink, param, semanticName); + continue; + } + if (!info.requiredType) + continue; + + builder.addTargetSystemValueDecoration(param, info.metalSystemValueName.getUnownedSlice()); + + // If the required type is different from the actual type, we need to insert a conversion. + if (info.requiredType != param->getFullType() && info.altRequiredType != param->getFullType()) + { + auto targetType = param->getFullType(); + builder.setInsertBefore(entryPoint.entryPointFunc->getFirstBlock()->getFirstOrdinaryInst()); + param->setFullType(info.requiredType); + List<IRUse*> uses; + for (auto use = param->firstUse; use; use = use->nextUse) + uses.add(use); + auto convertedValue = tryConvertValue(builder, param, targetType); + copyNameHintAndDebugDecorations(convertedValue, param); + if (!convertedValue) + { + // If we can't convert the value, report an error. + StringBuilder typeNameSB; + getTypeNameHint(typeNameSB, info.requiredType); + sink->diagnose(param->sourceLoc, Diagnostics::systemValueTypeIncompatible, semanticName, typeNameSB.produceString()); + } + else + { + for (auto use : uses) + builder.replaceOperand(use, convertedValue); + } + } + } + fixUpFuncType(entryPoint.entryPointFunc); + } + + void legalizeEntryPointForMetal(EntryPointInfo entryPoint, DiagnosticSink* sink) + { hoistEntryPointParameterFromStruct(entryPoint); packStageInParameters(entryPoint); - wrapReturnValueInStruct(entryPoint); + legalizeSystemValueParameters(entryPoint, sink); + wrapReturnValueInStruct(sink, entryPoint); legalizeMeshEntryPoint(entryPoint); legalizeDispatchMeshPayloadForMetal(entryPoint); } |
