summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/slang/core.meta.slang6
-rw-r--r--source/slang/hlsl.meta.slang20
-rw-r--r--source/slang/slang-ast-modifier.h4
-rw-r--r--source/slang/slang-ast-support-types.cpp24
-rw-r--r--source/slang/slang-ast-support-types.h18
-rw-r--r--source/slang/slang-check-expr.cpp46
-rw-r--r--source/slang/slang-check-modifier.cpp6
-rw-r--r--source/slang/slang-ir-autodiff.cpp2
-rw-r--r--source/slang/slang-ir-fuse-satcoop.cpp7
-rw-r--r--source/slang/slang-ir-glsl-legalize.cpp5
-rw-r--r--source/slang/slang-ir-insts.h19
-rw-r--r--source/slang/slang-ir-legalize-varying-params.cpp2
-rw-r--r--source/slang/slang-ir-link.cpp3
-rw-r--r--source/slang/slang-ir-util.cpp32
-rw-r--r--source/slang/slang-ir-util.h1
-rw-r--r--source/slang/slang-lower-to-ir.cpp9
-rw-r--r--tests/bugs/gh-4131.slang2
-rw-r--r--tests/language-feature/known-builtin-enum-test.slang22
18 files changed, 175 insertions, 53 deletions
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index b257ff49c..85cf3cf11 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -603,7 +603,7 @@ void static_assert(constexpr bool condition, NativeString errorMessage);
///
///
__magic_type(DifferentiableType)
-[KnownBuiltin("IDifferentiable")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::IDifferentiable))]
interface IDifferentiable
{
// Note: the compiler implementation requires the `Differential` associated type to be defined
@@ -646,7 +646,7 @@ interface IDifferentiable
/// @remarks Support for this interface is still experimental and subject to change.
///
__magic_type(DifferentiablePtrType)
-[KnownBuiltin("IDifferentiablePtr")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::IDifferentiablePtr))]
interface IDifferentiablePtrType
{
__builtin_requirement($( (int)BuiltinRequirementKind::DifferentialPtrType) )
@@ -4233,7 +4233,7 @@ attribute_syntax [PreferCheckpoint] : PreferCheckpointAttribute;
// @hidden:
__attributeTarget(DeclBase)
-attribute_syntax [KnownBuiltin(name : String)] : KnownBuiltinAttribute;
+attribute_syntax [KnownBuiltin(name : int)] : KnownBuiltinAttribute;
__attributeTarget(FunctionDeclBase)
attribute_syntax [__GLSLRequireShaderInputParameter(parameterNumber:int)] : GLSLRequireShaderInputParameterAttribute;
diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang
index f7efc3a51..1dcb0b7d4 100644
--- a/source/slang/hlsl.meta.slang
+++ b/source/slang/hlsl.meta.slang
@@ -6111,7 +6111,7 @@ __magic_type(HLSLPointStreamType)
__intrinsic_type($(kIROp_HLSLPointStreamType))
struct PointStream
{
- [KnownBuiltin("GeometryStreamAppend")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamAppend))]
void Append(T value)
{
__target_switch
@@ -6122,7 +6122,7 @@ struct PointStream
}
}
- [KnownBuiltin("GeometryStreamRestart")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamRestart))]
void RestartStrip()
{
__target_switch
@@ -6141,7 +6141,7 @@ __magic_type(HLSLLineStreamType)
__intrinsic_type($(kIROp_HLSLLineStreamType))
struct LineStream
{
- [KnownBuiltin("GeometryStreamAppend")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamAppend))]
void Append(T value)
{
__target_switch
@@ -6152,7 +6152,7 @@ struct LineStream
}
}
- [KnownBuiltin("GeometryStreamRestart")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamRestart))]
void RestartStrip()
{
__target_switch
@@ -6171,7 +6171,7 @@ __magic_type(HLSLTriangleStreamType)
__intrinsic_type($(kIROp_HLSLTriangleStreamType))
struct TriangleStream
{
- [KnownBuiltin("GeometryStreamAppend")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamAppend))]
void Append(T value)
{
__target_switch
@@ -6182,7 +6182,7 @@ struct TriangleStream
}
}
- [KnownBuiltin("GeometryStreamRestart")]
+ [KnownBuiltin($( (int)KnownBuiltinDeclName::GeometryStreamRestart))]
void RestartStrip()
{
__target_switch
@@ -10256,7 +10256,7 @@ __generic<T : __BuiltinType>
__glsl_version(450)
__glsl_extension(GL_EXT_fragment_shader_barycentric)
[require(glsl_hlsl_spirv, getattributeatvertex)]
-[KnownBuiltin("GetAttributeAtVertex")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::GetAttributeAtVertex))]
[__unsafeForceInlineEarly]
T GetAttributeAtVertex(__constref T attribute, uint vertexIndex)
{
@@ -18292,7 +18292,7 @@ void SetMeshOutputCounts(uint vertexCount, uint primitiveCount)
/// and provide the values for per-mesh payload parameters.
/// @return This function doesn't return.
/// @category meshshading
-[KnownBuiltin("DispatchMesh")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::DispatchMesh))]
[require(glsl_hlsl_metal_spirv, meshshading)]
[noRefInline]
void DispatchMesh<P>(uint threadGroupCountX, uint threadGroupCountY, uint threadGroupCountZ, __ref P meshPayload)
@@ -21579,7 +21579,7 @@ uint3 cudaBlockDim()
// the signature or behavior of this function should be adjusted for there).
//
//@hidden:
-[KnownBuiltin("saturated_cooperation")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::saturated_cooperation))]
func saturated_cooperation<A : __BuiltinType, B, C>(
cooperate : functype (A, B) -> C,
fallback : functype (A, B) -> C,
@@ -21610,7 +21610,7 @@ func __WaveReadLaneAtBuiltin<T : __BuiltinType>(T t, int i) -> T
// waveMatch: a function to return a mask of lanes with the same input as this one
// broadcast: a function which returns the value passed into it on the specified lane
//
-[KnownBuiltin("saturated_cooperation_using")]
+[KnownBuiltin($( (int)KnownBuiltinDeclName::saturated_cooperation_using))]
func saturated_cooperation_using<A, B, C>(
cooperate : functype (A, B) -> C,
fallback : functype (A, B) -> C,
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index fa073eb46..b5fa25418 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -1953,7 +1953,7 @@ class NoSideEffectAttribute : public Attribute
FIDDLE(...)
};
-/// A `[KnownBuiltin("name")]` attribute allows the compiler to
+/// A `[KnownBuiltin(name)]` attribute allows the compiler to
/// identify this declaration during compilation, despite obfuscation or
/// linkage removing optimizations
///
@@ -1961,7 +1961,7 @@ FIDDLE()
class KnownBuiltinAttribute : public Attribute
{
FIDDLE(...)
- FIDDLE() String name;
+ FIDDLE() IntVal* name;
};
/// A modifier that applies to types rather than declarations.
diff --git a/source/slang/slang-ast-support-types.cpp b/source/slang/slang-ast-support-types.cpp
index 3ac352f0a..7665fb6d4 100644
--- a/source/slang/slang-ast-support-types.cpp
+++ b/source/slang/slang-ast-support-types.cpp
@@ -96,4 +96,28 @@ void printDiagnosticArg(StringBuilder& sb, ParameterDirection direction)
}
}
+KnownBuiltinDeclName getKnownBuiltinDeclNameFromString(UnownedStringSlice name)
+{
+ if (name == "GeometryStreamAppend")
+ return KnownBuiltinDeclName::GeometryStreamAppend;
+ else if (name == "GeometryStreamRestart")
+ return KnownBuiltinDeclName::GeometryStreamRestart;
+ else if (name == "GetAttributeAtVertex")
+ return KnownBuiltinDeclName::GetAttributeAtVertex;
+ else if (name == "DispatchMesh")
+ return KnownBuiltinDeclName::DispatchMesh;
+ else if (name == "saturated_cooperation")
+ return KnownBuiltinDeclName::saturated_cooperation;
+ else if (name == "saturated_cooperation_using")
+ return KnownBuiltinDeclName::saturated_cooperation_using;
+ else if (name == "IDifferentiable")
+ return KnownBuiltinDeclName::IDifferentiable;
+ else if (name == "IDifferentiablePtr")
+ return KnownBuiltinDeclName::IDifferentiablePtr;
+ else if (name == "NullDifferential")
+ return KnownBuiltinDeclName::NullDifferential;
+ else
+ return KnownBuiltinDeclName::COUNT;
+}
+
} // namespace Slang
diff --git a/source/slang/slang-ast-support-types.h b/source/slang/slang-ast-support-types.h
index 6f13e7296..8fe432bc5 100644
--- a/source/slang/slang-ast-support-types.h
+++ b/source/slang/slang-ast-support-types.h
@@ -221,6 +221,24 @@ FIDDLE() namespace Slang
char const* getGLSLNameForImageFormat(ImageFormat format);
+ /// Enum for known built-in function names to replace string-based comparisons
+ enum class KnownBuiltinDeclName : uint32_t
+ {
+ GeometryStreamAppend,
+ GeometryStreamRestart,
+ GetAttributeAtVertex,
+ DispatchMesh,
+ saturated_cooperation,
+ saturated_cooperation_using,
+ IDifferentiable,
+ IDifferentiablePtr,
+ NullDifferential,
+ COUNT
+ };
+
+ /// Convert string name to KnownBuiltinDeclName enum
+ KnownBuiltinDeclName getKnownBuiltinDeclNameFromString(UnownedStringSlice name);
+
// TODO(tfoley): We should ditch this enumeration
// and just use the IR opcodes that represent these
// types directly. The one major complication there
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index c7e58a888..9325eda61 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -15,6 +15,7 @@
#include "slang-ast-decl.h"
#include "slang-ast-natural-layout.h"
#include "slang-ast-print.h"
+#include "slang-ast-support-types.h"
#include "slang-ast-synthesis.h"
#include "slang-lookup-spirv.h"
#include "slang-lookup.h"
@@ -4524,29 +4525,32 @@ void SemanticsExprVisitor::maybeCheckKnownBuiltinInvocation(Expr* invokeExpr)
auto knownBuiltinAttr = callee->findModifier<KnownBuiltinAttribute>();
if (!knownBuiltinAttr)
return;
- if (knownBuiltinAttr->name == "GetAttributeAtVertex")
+ if (auto constantIntVal = as<ConstantIntVal>(knownBuiltinAttr->name))
{
- if (checkedInvokeExpr->arguments.getCount() != 2)
- return;
- auto vertexAttributeArg = checkedInvokeExpr->arguments[0];
- auto vertexAttributeArgDeclRefExpr = as<DeclRefExpr>(vertexAttributeArg);
- if (!vertexAttributeArgDeclRefExpr)
+ if (constantIntVal->getValue() == (int)KnownBuiltinDeclName::GetAttributeAtVertex)
{
- getSink()->diagnose(
- invokeExpr,
- Diagnostics::getAttributeAtVertexMustReferToPerVertexInput);
- return;
- }
- auto vertexAttributeArgDecl = vertexAttributeArgDeclRefExpr->declRef.getDecl();
- if (!vertexAttributeArgDecl)
- return;
- if (!vertexAttributeArgDecl->findModifier<PerVertexModifier>() &&
- !vertexAttributeArgDecl->findModifier<HLSLNoInterpolationModifier>())
- {
- getSink()->diagnose(
- vertexAttributeArgDeclRefExpr,
- Diagnostics::getAttributeAtVertexMustReferToPerVertexInput);
- return;
+ if (checkedInvokeExpr->arguments.getCount() != 2)
+ return;
+ auto vertexAttributeArg = checkedInvokeExpr->arguments[0];
+ auto vertexAttributeArgDeclRefExpr = as<DeclRefExpr>(vertexAttributeArg);
+ if (!vertexAttributeArgDeclRefExpr)
+ {
+ getSink()->diagnose(
+ invokeExpr,
+ Diagnostics::getAttributeAtVertexMustReferToPerVertexInput);
+ return;
+ }
+ auto vertexAttributeArgDecl = vertexAttributeArgDeclRefExpr->declRef.getDecl();
+ if (!vertexAttributeArgDecl)
+ return;
+ if (!vertexAttributeArgDecl->findModifier<PerVertexModifier>() &&
+ !vertexAttributeArgDecl->findModifier<HLSLNoInterpolationModifier>())
+ {
+ getSink()->diagnose(
+ vertexAttributeArgDeclRefExpr,
+ Diagnostics::getAttributeAtVertexMustReferToPerVertexInput);
+ return;
+ }
}
}
}
diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp
index 7779957ef..0561a7084 100644
--- a/source/slang/slang-check-modifier.cpp
+++ b/source/slang/slang-check-modifier.cpp
@@ -1060,13 +1060,13 @@ Modifier* SemanticsVisitor::validateAttribute(
{
SLANG_ASSERT(attr->args.getCount() == 1);
- String name;
- if (!checkLiteralStringVal(attr->args[0], &name))
+ ConstantIntVal* value = checkConstantEnumVal(attr->args[0]);
+ if (!value)
{
return nullptr;
}
- knownBuiltinAttr->name = name;
+ knownBuiltinAttr->name = value;
}
else if (auto pyExportAttr = as<PyExportAttribute>(attr))
{
diff --git a/source/slang/slang-ir-autodiff.cpp b/source/slang/slang-ir-autodiff.cpp
index 5a8dc9074..7876d7eeb 100644
--- a/source/slang/slang-ir-autodiff.cpp
+++ b/source/slang/slang-ir-autodiff.cpp
@@ -1046,7 +1046,7 @@ IRInst* AutoDiffSharedContext::findDifferentiableInterface()
{
if (auto decor = intf->findDecoration<IRKnownBuiltinDecoration>())
{
- if (decor->getName() == toSlice("IDifferentiable"))
+ if (decor->getName() == KnownBuiltinDeclName::IDifferentiable)
{
return globalInst;
}
diff --git a/source/slang/slang-ir-fuse-satcoop.cpp b/source/slang/slang-ir-fuse-satcoop.cpp
index ec0380efc..fcb3dd5f7 100644
--- a/source/slang/slang-ir-fuse-satcoop.cpp
+++ b/source/slang/slang-ir-fuse-satcoop.cpp
@@ -475,7 +475,12 @@ IRCall* isKnownFunction(const char* n, IRInst* i)
return nullptr;
auto h = inner->findDecoration<IRKnownBuiltinDecoration>();
- if (!h || h->getName() != n)
+ if (!h)
+ return nullptr;
+
+ // Convert string to enum for comparison
+ auto expectedEnum = getKnownBuiltinDeclNameFromString(UnownedStringSlice(n));
+ if (h->getName() != expectedEnum)
return nullptr;
return call;
}
diff --git a/source/slang/slang-ir-glsl-legalize.cpp b/source/slang/slang-ir-glsl-legalize.cpp
index fc1bcfa5a..f001384a4 100644
--- a/source/slang/slang-ir-glsl-legalize.cpp
+++ b/source/slang/slang-ir-glsl-legalize.cpp
@@ -3366,8 +3366,7 @@ void legalizeEntryPointParameterForGLSL(
if (callee->getOp() != kIROp_Func)
continue;
- if (getBuiltinFuncName(callee) !=
- UnownedStringSlice::fromLiteral("GeometryStreamAppend"))
+ if (getBuiltinFuncEnum(callee) != KnownBuiltinDeclName::GeometryStreamAppend)
{
// If we are calling a function that takes a output stream as a parameter,
// we need to add it to the work list to be processed.
@@ -4386,7 +4385,7 @@ void legalizeDispatchMeshPayloadForGLSL(IRModule* module)
{
if (const auto dec = func->findDecoration<IRKnownBuiltinDecoration>())
{
- if (dec->getName() == "DispatchMesh")
+ if (dec->getName() == KnownBuiltinDeclName::DispatchMesh)
{
SLANG_ASSERT(!dispatchMeshFunc && "Multiple DispatchMesh functions found");
dispatchMeshFunc = func;
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index b0a0c74f9..93979bdbe 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -7,6 +7,7 @@
//
// TODO: the builder probably needs its own file.
+#include "slang-ast-support-types.h"
#include "slang-capability.h"
#include "slang-compiler.h"
#include "slang-ir.h"
@@ -678,8 +679,8 @@ struct IRKnownBuiltinDecoration : IRDecoration
{
FIDDLE(leafInst())
- IRStringLit* getNameOperand() { return cast<IRStringLit>(getOperand(0)); }
- UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); }
+ IRIntLit* getNameOperand() { return cast<IRIntLit>(getOperand(0)); }
+ KnownBuiltinDeclName getName() { return KnownBuiltinDeclName(getIntVal(getNameOperand())); }
};
FIDDLE()
@@ -5341,9 +5342,21 @@ public:
addDecoration(value, d, maxCount);
}
+ void addKnownBuiltinDecoration(IRInst* value, KnownBuiltinDeclName enumValue)
+ {
+ addDecoration(
+ value,
+ kIROp_KnownBuiltinDecoration,
+ getIntValue(getIntType(), IRIntegerValue(enumValue)));
+ }
+
void addKnownBuiltinDecoration(IRInst* value, UnownedStringSlice const& name)
{
- addDecoration(value, kIROp_KnownBuiltinDecoration, getStringValue(name));
+ auto enumValue = getKnownBuiltinDeclNameFromString(name);
+ addDecoration(
+ value,
+ kIROp_KnownBuiltinDecoration,
+ getIntValue(getIntType(), IRIntegerValue(enumValue)));
}
void addMemoryQualifierSetDecoration(IRInst* inst, IRIntegerValue flags)
diff --git a/source/slang/slang-ir-legalize-varying-params.cpp b/source/slang/slang-ir-legalize-varying-params.cpp
index 949962a5c..ca65a37c1 100644
--- a/source/slang/slang-ir-legalize-varying-params.cpp
+++ b/source/slang/slang-ir-legalize-varying-params.cpp
@@ -3511,7 +3511,7 @@ protected:
{
if (const auto dec = func->findDecoration<IRKnownBuiltinDecoration>())
{
- if (dec->getName() == "DispatchMesh")
+ if (dec->getName() == KnownBuiltinDeclName::DispatchMesh)
{
SLANG_ASSERT(!dispatchMeshFunc && "Multiple DispatchMesh functions found");
dispatchMeshFunc = func;
diff --git a/source/slang/slang-ir-link.cpp b/source/slang/slang-ir-link.cpp
index 8f48e83dc..d8bc041fb 100644
--- a/source/slang/slang-ir-link.cpp
+++ b/source/slang/slang-ir-link.cpp
@@ -705,7 +705,8 @@ bool shouldDeepCloneWitnessTable(IRSpecContextBase* context, IRWitnessTable* tab
case kIROp_KnownBuiltinDecoration:
{
auto name = as<IRKnownBuiltinDecoration>(decor)->getName();
- if (name == toSlice("IDifferentiable") || name == toSlice("IDifferentiablePtr"))
+ if (name == KnownBuiltinDeclName::IDifferentiable ||
+ name == KnownBuiltinDeclName::IDifferentiablePtr)
return context->getShared()->useAutodiff;
break;
}
diff --git a/source/slang/slang-ir-util.cpp b/source/slang/slang-ir-util.cpp
index 69bd2c6c2..c8d76569f 100644
--- a/source/slang/slang-ir-util.cpp
+++ b/source/slang/slang-ir-util.cpp
@@ -1775,6 +1775,38 @@ UnownedStringSlice getBuiltinFuncName(IRInst* callee)
auto decor = getResolvedInstForDecorations(callee)->findDecoration<IRKnownBuiltinDecoration>();
if (!decor)
return UnownedStringSlice();
+
+ // For backward compatibility, convert enum back to string
+ switch (decor->getName())
+ {
+ case KnownBuiltinDeclName::GeometryStreamAppend:
+ return UnownedStringSlice::fromLiteral("GeometryStreamAppend");
+ case KnownBuiltinDeclName::GeometryStreamRestart:
+ return UnownedStringSlice::fromLiteral("GeometryStreamRestart");
+ case KnownBuiltinDeclName::GetAttributeAtVertex:
+ return UnownedStringSlice::fromLiteral("GetAttributeAtVertex");
+ case KnownBuiltinDeclName::DispatchMesh:
+ return UnownedStringSlice::fromLiteral("DispatchMesh");
+ case KnownBuiltinDeclName::saturated_cooperation:
+ return UnownedStringSlice::fromLiteral("saturated_cooperation");
+ case KnownBuiltinDeclName::saturated_cooperation_using:
+ return UnownedStringSlice::fromLiteral("saturated_cooperation_using");
+ case KnownBuiltinDeclName::IDifferentiable:
+ return UnownedStringSlice::fromLiteral("IDifferentiable");
+ case KnownBuiltinDeclName::IDifferentiablePtr:
+ return UnownedStringSlice::fromLiteral("IDifferentiablePtr");
+ case KnownBuiltinDeclName::NullDifferential:
+ return UnownedStringSlice::fromLiteral("NullDifferential");
+ default:
+ return UnownedStringSlice();
+ }
+}
+
+KnownBuiltinDeclName getBuiltinFuncEnum(IRInst* callee)
+{
+ auto decor = getResolvedInstForDecorations(callee)->findDecoration<IRKnownBuiltinDecoration>();
+ if (!decor)
+ return KnownBuiltinDeclName::COUNT; // Use COUNT as invalid value
return decor->getName();
}
diff --git a/source/slang/slang-ir-util.h b/source/slang/slang-ir-util.h
index e325fbdc2..f47026185 100644
--- a/source/slang/slang-ir-util.h
+++ b/source/slang/slang-ir-util.h
@@ -327,6 +327,7 @@ IRBlock* getBlock(IRInst* inst);
IRVarLayout* findVarLayout(IRInst* value);
UnownedStringSlice getBuiltinFuncName(IRInst* callee);
+KnownBuiltinDeclName getBuiltinFuncEnum(IRInst* callee);
// Run an operation over every block in a module
template<typename F>
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index ed4336ff9..4b232e829 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1444,9 +1444,12 @@ static void addLinkageDecoration(
// We add this to the internal instruction, like other name-like
// decorations, for instance "nameHint". This prevents it becoming
// lost during specialization.
- builder->addKnownBuiltinDecoration(
- inInst,
- knownBuiltinModifier->name.getUnownedSlice());
+ auto constantIntVal = as<ConstantIntVal>(knownBuiltinModifier->name);
+ if (constantIntVal)
+ {
+ auto enumValue = constantIntVal->getValue();
+ builder->addKnownBuiltinDecoration(inInst, KnownBuiltinDeclName(enumValue));
+ }
}
}
if (as<InterfaceDecl>(decl->parentDecl) &&
diff --git a/tests/bugs/gh-4131.slang b/tests/bugs/gh-4131.slang
index d72bc5d0d..59eaff868 100644
--- a/tests/bugs/gh-4131.slang
+++ b/tests/bugs/gh-4131.slang
@@ -16,7 +16,7 @@ StructuredBuffer<TypeB> b_buffer : register(t0, space0);
struct VertexIn {
int32_t vert_idx : SV_VertexID;
- [[KnownBuiltin("DrawIndex")]]
+ [[KnownBuiltin(0)]]
uint32_t draw_idx : POSITION0;
};
diff --git a/tests/language-feature/known-builtin-enum-test.slang b/tests/language-feature/known-builtin-enum-test.slang
new file mode 100644
index 000000000..cf2c9c63e
--- /dev/null
+++ b/tests/language-feature/known-builtin-enum-test.slang
@@ -0,0 +1,22 @@
+//TEST:COMPARE_COMPUTE(filecheck-buffer=CHECK):-cpu -output-using-type
+
+//TEST_INPUT: set outputBuffer = out ubuffer(data=[0 0 0 0], stride=4)
+RWStructuredBuffer<float> outputBuffer;
+
+// Test that KnownBuiltin attribute works with enum-based system
+// Using GeometryStreamAppend enum value (0) for testing
+static const int GEOMETRY_STREAM_APPEND_BUILTIN = 0;
+
+[KnownBuiltin(GEOMETRY_STREAM_APPEND_BUILTIN)]
+void testKnownBuiltin()
+{
+ // This function just needs to exist to test attribute processing
+}
+
+[numthreads(1,1,1)]
+void computeMain()
+{
+ // Simple test that the code compiles and runs
+ outputBuffer[0] = 42.0f;
+ // CHECK: 42.0
+} \ No newline at end of file