From d8a8559a5baebb81361b15cf86d28c9e8019b177 Mon Sep 17 00:00:00 2001 From: Jay Kwak <82421531+jkwak-work@users.noreply.github.com> Date: Wed, 5 Feb 2025 16:23:40 -0800 Subject: maxtessfactor attribute should take a floating point value (#6289) * maxtessfactor attribute should take a floating point value * Support integer value on maxtessfactor --- source/slang/slang-check-impl.h | 1 + source/slang/slang-check-modifier.cpp | 28 +++++++++++++++++++++++++--- source/slang/slang-diagnostic-defs.h | 6 ++++++ source/slang/slang-emit-hlsl.cpp | 32 ++++++++++++++++++++++++++++++++ source/slang/slang-emit-hlsl.h | 1 + source/slang/slang-ir-inst-defs.h | 1 + source/slang/slang-ir-insts.h | 12 ++++++++++++ source/slang/slang-ir.cpp | 5 +++++ source/slang/slang-lower-to-ir.cpp | 23 +++++++++++++++++++++++ 9 files changed, 106 insertions(+), 3 deletions(-) (limited to 'source') diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index e6520cfd3..350362a0e 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -1678,6 +1678,7 @@ public: AttributeDecl* lookUpAttributeDecl(Name* attributeName, Scope* scope); + bool hasFloatArgs(Attribute* attr, int numArgs); bool hasIntArgs(Attribute* attr, int numArgs); bool hasStringArgs(Attribute* attr, int numArgs); diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index 6e451b5cf..741823a65 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -312,6 +312,22 @@ AttributeDecl* SemanticsVisitor::lookUpAttributeDecl(Name* attributeName, Scope* return attrDecl; } +bool SemanticsVisitor::hasFloatArgs(Attribute* attr, int numArgs) +{ + if (int(attr->args.getCount()) != numArgs) + { + return false; + } + for (int i = 0; i < numArgs; ++i) + { + if (!as(attr->args[i]) && !as(attr->args[i])) + { + return false; + } + } + return true; +} + bool SemanticsVisitor::hasIntArgs(Attribute* attr, int numArgs) { if (int(attr->args.getCount()) != numArgs) @@ -692,9 +708,8 @@ Modifier* SemanticsVisitor::validateAttribute( } } else if ( - (as(attr)) || (as(attr)) || - (as(attr)) || (as(attr)) || - (as(attr))) + (as(attr)) || (as(attr)) || + (as(attr)) || (as(attr))) { // Let it go thru iff single string attribute if (!hasStringArgs(attr, 1)) @@ -724,6 +739,13 @@ Modifier* SemanticsVisitor::validateAttribute( sink->diagnose(attr, Diagnostics::attributeExpectedStringArg, attr->keywordName, 1); } } + else if (as(attr)) + { + if (!hasFloatArgs(attr, 1)) + { + getSink()->diagnose(attr, Diagnostics::expectedSingleFloatArg, attr->keywordName); + } + } else if (as(attr)) { // Let it go thru iff single integral attribute diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index 4d037b68e..a1768415e 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1045,6 +1045,12 @@ DIAGNOSTIC( attributeExpectedStringArg, "attribute '$0' expects argument $1 to be string") +DIAGNOSTIC( + 31009, + Error, + expectedSingleFloatArg, + "attribute '$0' expects a single floating point argument") + DIAGNOSTIC(31100, Error, unknownStageName, "unknown stage name '$0'") DIAGNOSTIC(31101, Error, unknownImageFormatName, "unknown image format '$0'") DIAGNOSTIC(31101, Error, unknownDiagnosticName, "unknown diagnostic '$0'") diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 53545b31f..9ebec0893 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -60,6 +60,32 @@ void HLSLSourceEmitter::_emitHLSLDecorationSingleInt( m_writer->emit(")]\n"); } +void HLSLSourceEmitter::_emitHLSLDecorationSingleFloat( + const char* name, + IRFunc* entryPoint, + IRFloatLit* val) +{ + SLANG_UNUSED(entryPoint); + SLANG_ASSERT(val); + + m_writer->emit("["); + m_writer->emit(name); + m_writer->emit("("); + + switch (val->getOp()) + { + default: + SLANG_UNEXPECTED("needed a known floating point value"); + break; + + case kIROp_FloatLit: + m_writer->emit(static_cast(val)->value.floatVal); + break; + } + + m_writer->emit(")]\n"); +} + void HLSLSourceEmitter::_emitHLSLRegisterSemantic( LayoutResourceKind kind, EmitVarChain* chain, @@ -511,6 +537,12 @@ void HLSLSourceEmitter::emitEntryPointAttributesImpl( _emitHLSLDecorationSingleString("outputtopology", irFunc, decor->getTopology()); } + /* [maxtessfactor(16.0)] */ + if (auto decor = irFunc->findDecoration()) + { + _emitHLSLDecorationSingleFloat("maxtessfactor", irFunc, decor->getMaxTessFactor()); + } + /* [outputcontrolpoints(4)] */ if (auto decor = irFunc->findDecoration()) { diff --git a/source/slang/slang-emit-hlsl.h b/source/slang/slang-emit-hlsl.h index 07c7af3d2..28319f93a 100644 --- a/source/slang/slang-emit-hlsl.h +++ b/source/slang/slang-emit-hlsl.h @@ -118,6 +118,7 @@ protected: void _emitHLSLDecorationSingleString(const char* name, IRFunc* entryPoint, IRStringLit* val); void _emitHLSLDecorationSingleInt(const char* name, IRFunc* entryPoint, IRIntLit* val); + void _emitHLSLDecorationSingleFloat(const char* name, IRFunc* entryPoint, IRFloatLit* val); void _emitStageAccessSemantic(IRStageAccessDecoration* decoration, const char* name); }; diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index d9c543efa..59a6852b1 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -845,6 +845,7 @@ INST_RANGE(BindingQuery, GetRegisterIndex, GetRegisterSpace) INST(DownstreamModuleExportDecoration, downstreamModuleExport, 0, 0) INST(DownstreamModuleImportDecoration, downstreamModuleImport, 0, 0) INST(PatchConstantFuncDecoration, patchConstantFunc, 1, 0) + INST(MaxTessFactorDecoration, maxTessFactor, 1, 0) INST(OutputControlPointsDecoration, outputControlPoints, 1, 0) INST(OutputTopologyDecoration, outputTopology, 1, 0) INST(PartitioningDecoration, partioning, 1, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index c342039a5..fcafe4bc6 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -515,6 +515,17 @@ struct IRNVAPISlotDecoration : IRDecoration UnownedStringSlice getSpaceName() { return getSpaceNameOperand()->getStringSlice(); } }; +struct IRMaxTessFactorDecoration : IRDecoration +{ + enum + { + kOp = kIROp_MaxTessFactorDecoration + }; + IR_LEAF_ISA(MaxTessFactorDecoration) + + IRFloatLit* getMaxTessFactor() { return cast(getOperand(0)); } +}; + struct IROutputControlPointsDecoration : IRDecoration { enum @@ -3656,6 +3667,7 @@ public: IRBasicType* getUInt64Type(); IRBasicType* getUInt16Type(); IRBasicType* getUInt8Type(); + IRBasicType* getFloatType(); IRBasicType* getCharType(); IRStringType* getStringType(); IRNativeStringType* getNativeStringType(); diff --git a/source/slang/slang-ir.cpp b/source/slang/slang-ir.cpp index 6a7564e67..3314567f1 100644 --- a/source/slang/slang-ir.cpp +++ b/source/slang/slang-ir.cpp @@ -2678,6 +2678,11 @@ IRBasicType* IRBuilder::getUInt8Type() return (IRBasicType*)getType(kIROp_UInt8Type); } +IRBasicType* IRBuilder::getFloatType() +{ + return (IRBasicType*)getType(kIROp_FloatType); +} + IRBasicType* IRBuilder::getCharType() { return (IRBasicType*)getType(kIROp_CharType); diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index a966189a0..cac157f9b 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -9986,6 +9986,24 @@ struct DeclLoweringVisitor : DeclVisitor } } + IRFloatLit* _getFloatFromAttribute(IRBuilder* builder, Attribute* attrib, Index index = 0) + { + SLANG_ASSERT(attrib->args.getCount() > index); + Expr* expr = attrib->args[index]; + + if (auto floatLitExpr = as(expr)) + { + return as( + builder->getFloatValue(builder->getFloatType(), floatLitExpr->value)); + } + + auto intLitExpr = as(expr); + SLANG_ASSERT(intLitExpr); + return as(builder->getFloatValue( + builder->getFloatType(), + (IRFloatingPointValue)(intLitExpr->value))); + } + IRIntLit* _getIntLitFromAttribute(IRBuilder* builder, Attribute* attrib, Index index = 0) { SLANG_ASSERT(attrib->args.getCount() > index); @@ -10520,6 +10538,11 @@ struct DeclLoweringVisitor : DeclVisitor IRStringLit* stringLit = _getStringLitFromAttribute(getBuilder(), outputTopAttr); getBuilder()->addDecoration(irFunc, kIROp_OutputTopologyDecoration, stringLit); } + else if (auto maxTessFactortAttr = as(modifier)) + { + IRFloatLit* floatLit = _getFloatFromAttribute(getBuilder(), maxTessFactortAttr); + getBuilder()->addDecoration(irFunc, kIROp_MaxTessFactorDecoration, floatLit); + } else if (auto outputCtrlPtAttr = as(modifier)) { IRIntLit* intLit = _getIntLitFromAttribute(getBuilder(), outputCtrlPtAttr); -- cgit v1.2.3