diff options
| author | Yong He <yonghe@outlook.com> | 2024-06-11 12:31:37 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-11 12:31:37 -0700 |
| commit | 6909d65c77bb4e7c9cfb281bd1684a58d5f8b94d (patch) | |
| tree | 396a628b7fda779dcc6e820e86d44e29d0c7be95 /source/slang/slang-emit-spirv.cpp | |
| parent | ef20d9309674dc8c25a9798d95138cf739299928 (diff) | |
SPIRV backend: add support for tessellation stages, (#4336)
Diffstat (limited to 'source/slang/slang-emit-spirv.cpp')
| -rw-r--r-- | source/slang/slang-emit-spirv.cpp | 102 |
1 files changed, 97 insertions, 5 deletions
diff --git a/source/slang/slang-emit-spirv.cpp b/source/slang/slang-emit-spirv.cpp index 4f7410f00..fd4b1d491 100644 --- a/source/slang/slang-emit-spirv.cpp +++ b/source/slang/slang-emit-spirv.cpp @@ -2963,6 +2963,15 @@ struct SPIRVEmitContext result = emitOpAtomicIDecrement(parent, inst, inst->getFullType(), inst->getOperand(0), memoryScope, memorySemantics); } break; + case kIROp_ControlBarrier: + { + IRBuilder builder{ inst }; + const auto executionScope = emitIntConstant(IRIntegerValue{ SpvScopeWorkgroup }, builder.getUIntType()); + const auto memoryScope = emitIntConstant(IRIntegerValue{ SpvScopeInvocation }, builder.getUIntType()); + const auto memorySemantics = emitIntConstant(IRIntegerValue{ SpvMemorySemanticsMaskNone }, builder.getUIntType()); + emitInst(parent, inst, SpvOpControlBarrier, executionScope, memoryScope, memorySemantics); + } + break; } if (result) emitDecorations(inst, getID(result)); @@ -3323,6 +3332,29 @@ struct SPIRVEmitContext requireSPIRVCapability(SpvCapabilityMeshShadingEXT); ensureExtensionDeclaration(UnownedStringSlice("SPV_EXT_mesh_shader")); break; + case Stage::Hull: + { + requireSPIRVCapability(SpvCapabilityTessellation); + + SpvExecutionMode mode = SpvExecutionModeSpacingEqual; + if (auto partitioningDecor = entryPoint->findDecoration<IRPartitioningDecoration>()) + { + auto arg = partitioningDecor->getPartitioning()->getStringSlice(); + if (arg.caseInsensitiveEquals(toSlice("integer"))) + mode = SpvExecutionModeSpacingEqual; + else if (arg.caseInsensitiveEquals(toSlice("fractional_even"))) + mode = SpvExecutionModeSpacingFractionalEven; + else if (arg.caseInsensitiveEquals(toSlice("fractional_odd"))) + mode = SpvExecutionModeSpacingFractionalOdd; + else + m_sink->diagnose(partitioningDecor, Diagnostics::unknownTessPartitioning, arg); + } + requireSPIRVExecutionMode(nullptr, getIRInstSpvID(entryPoint), mode); + break; + } + case Stage::Domain: + requireSPIRVCapability(SpvCapabilityTessellation); + break; default: break; } @@ -3463,13 +3495,36 @@ struct SPIRVEmitContext case kIROp_OutputTopologyDecoration: { + auto entryPoint = decoration->getParent(); + IREntryPointDecoration* entryPointDecor = entryPoint ? entryPoint->findDecoration<IREntryPointDecoration>() : nullptr; + const auto o = cast<IROutputTopologyDecoration>(decoration); const auto t = o->getTopology()->getStringSlice(); - const auto m = - t == "triangle" ? SpvExecutionModeOutputTrianglesEXT - : t == "line" ? SpvExecutionModeOutputLinesEXT - : t == "point" ? SpvExecutionModeOutputPoints - : SpvExecutionModeMax; + + SpvExecutionMode m = SpvExecutionModeMax; + if (entryPointDecor) + { + switch (entryPointDecor->getProfile().getStage()) + { + case Stage::Domain: + case Stage::Hull: + if (t == "triangle_cw") + m = SpvExecutionModeVertexOrderCw; + else if (t == "triangle_ccw") + m = SpvExecutionModeVertexOrderCcw; + break; + } + } + if (m == SpvExecutionModeMax) + { + if (t == "triangle") + m = SpvExecutionModeOutputTrianglesEXT; + else if (t == "line") + m = SpvExecutionModeOutputTrianglesEXT; + else if (t == "point") + m = SpvExecutionModeOutputPoints; + } + SLANG_ASSERT(m != SpvExecutionModeMax); requireSPIRVExecutionMode(decoration, dstID, m); } @@ -3544,6 +3599,31 @@ struct SPIRVEmitContext dstID, SpvDecorationPerVertexKHR); break; + case kIROp_OutputControlPointsDecoration: + requireSPIRVExecutionMode( + decoration, + dstID, + SpvExecutionModeOutputVertices, + SpvLiteralInteger::from32(int32_t(getIntVal(decoration->getOperand(0))))); + break; + case kIROp_DomainDecoration: + { + auto domain = cast<IRDomainDecoration>(decoration); + SpvExecutionMode mode = SpvExecutionModeMax; + auto domainName = as<IRStringLit>(domain->getDomain()); + if (!domainName) + break; + auto domainStr = domainName->getStringSlice(); + if (domainStr.startsWithCaseInsensitive(toSlice("tri"))) + mode = SpvExecutionModeTriangles; + else if (domainStr.caseInsensitiveEquals(toSlice("quad"))) + mode = SpvExecutionModeQuads; + else if (domainStr.caseInsensitiveEquals(toSlice("isoline"))) + mode = SpvExecutionModeIsolines; + if (mode != SpvExecutionModeMax) + requireSPIRVExecutionMode(decoration, dstID, mode); + } + break; case kIROp_MemoryQualifierSetDecoration: { auto collection = as<IRMemoryQualifierSetDecoration>(decoration); @@ -3941,6 +4021,18 @@ struct SPIRVEmitContext varInst, builtinVal ); + switch (builtinVal) + { + case SpvBuiltInTessLevelInner: + case SpvBuiltInTessLevelOuter: + emitOpDecorate( + getSection(SpvLogicalSectionID::Annotations), + nullptr, + varInst, + SpvDecorationPatch + ); + break; + } m_builtinGlobalVars[key] = varInst; maybeEmitFlatDecorationForBuiltinVar(irInst, varInst); |
