summaryrefslogtreecommitdiff
path: root/source/slang/slang-emit-metal.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-04-30 09:57:54 -0700
committerGitHub <noreply@github.com>2024-04-30 09:57:54 -0700
commitf1221b80c3c5f59ed533147825ea414bef5e9df2 (patch)
tree2b737438f2fe82d40035118a34b6d7074991f5a6 /source/slang/slang-emit-metal.cpp
parent019d68fc14dd006c179417ffdb06827abe089a53 (diff)
Metal: Vertex/Fragment builtin and layouts. (#4044)
* Metal: Vertex/Fragment builtin and layouts. * Fix. * Fix test. * Emit user semantic on vertex/fragment attributes.
Diffstat (limited to 'source/slang/slang-emit-metal.cpp')
-rw-r--r--source/slang/slang-emit-metal.cpp128
1 files changed, 126 insertions, 2 deletions
diff --git a/source/slang/slang-emit-metal.cpp b/source/slang/slang-emit-metal.cpp
index 3773b7c2a..7580ed74d 100644
--- a/source/slang/slang-emit-metal.cpp
+++ b/source/slang/slang-emit-metal.cpp
@@ -128,8 +128,13 @@ void MetalSourceEmitter::emitFuncParamLayoutImpl(IRInst* param)
m_writer->emit(rr->getOffset());
m_writer->emit(")]]");
break;
+ case LayoutResourceKind::VaryingInput:
+ m_writer->emit(" [[stage_in]]");
+ break;
}
}
+ if (auto sysSemanticAttr = layout->findSystemValueSemanticAttr())
+ _emitSystemSemantic(sysSemanticAttr->getName(), sysSemanticAttr->getIndex());
}
void MetalSourceEmitter::emitParameterGroupImpl(IRGlobalParam* varDecl, IRUniformParameterGroupType* type)
@@ -610,11 +615,130 @@ void MetalSourceEmitter::emitRateQualifiersAndAddressSpaceImpl(IRRate* rate, [[m
}
}
+void MetalSourceEmitter::_emitSystemSemantic(UnownedStringSlice semanticName, IRIntegerValue semanticIndex)
+{
+ 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")))
+ {
+ 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]]");
+ }
+ else
+ {
+ m_writer->emit(" [[user(");
+ m_writer->emit(semanticName);
+ if (semanticIndex != 0)
+ {
+ m_writer->emit("_");
+ m_writer->emit(semanticIndex);
+ }
+ m_writer->emit(")]]");
+ }
+}
+
void MetalSourceEmitter::emitSemanticsImpl(IRInst* inst, bool allowOffsets)
{
- // Metal does not use semantics.
- SLANG_UNUSED(inst);
SLANG_UNUSED(allowOffsets);
+ if (inst->getOp() == kIROp_StructKey)
+ {
+ // Only emit [[attribute(n)]] on struct keys.
+ bool hasSemanticFromLayout = false;
+ if (auto varLayout = findVarLayout(inst))
+ {
+ for (auto attr : varLayout->getAllAttrs())
+ {
+ if (auto offsetAttr = as<IRVarOffsetAttr>(attr))
+ {
+ if (offsetAttr->getResourceKind() == LayoutResourceKind::MetalAttribute)
+ {
+ m_writer->emit(" [[attribute(");
+ m_writer->emit(offsetAttr->getOffset());
+ m_writer->emit(")]]");
+ }
+ }
+ else if (auto semanticAttr = as<IRSemanticAttr>(attr))
+ {
+ auto semanticName = String(semanticAttr->getName()).toUpper();
+ _emitSystemSemantic(semanticAttr->getName(), semanticAttr->getIndex());
+ hasSemanticFromLayout = true;
+ }
+ }
+
+ }
+ if (!hasSemanticFromLayout)
+ {
+ if (auto semanticDecor = inst->findDecoration<IRSemanticDecoration>())
+ {
+ _emitSystemSemantic(semanticDecor->getSemanticName(), semanticDecor->getSemanticIndex());
+ }
+ }
+ }
}
void MetalSourceEmitter::_emitStageAccessSemantic(IRStageAccessDecoration* decoration, const char* name)