diff options
| author | Yong He <yonghe@outlook.com> | 2024-04-30 09:57:54 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-30 09:57:54 -0700 |
| commit | f1221b80c3c5f59ed533147825ea414bef5e9df2 (patch) | |
| tree | 2b737438f2fe82d40035118a34b6d7074991f5a6 /source/slang/slang-emit-metal.cpp | |
| parent | 019d68fc14dd006c179417ffdb06827abe089a53 (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.cpp | 128 |
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) |
