summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2024-12-17 22:30:22 -0800
committerGitHub <noreply@github.com>2024-12-17 22:30:22 -0800
commit45af2467289bd39baff0269bb7de8a538f617dec (patch)
treede45c041f03d0e6b8d72235edbee7b7671220c0c
parent6e24244832d9032f0993cb088af625238096b723 (diff)
Add verification logic on push and specialization constants. (#5887)
* Add verification logic on push and specialization constants. * format code --------- Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com>
-rw-r--r--source/slang/slang-check-decl.cpp41
-rw-r--r--source/slang/slang-diagnostic-defs.h17
-rw-r--r--source/slang/slang-parameter-binding.cpp2
-rw-r--r--tests/diagnostics/specialization-constants.slang16
-rw-r--r--tests/spirv/push-constant-space.slang18
5 files changed, 91 insertions, 3 deletions
diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp
index e94a3eb10..e2af70fa9 100644
--- a/source/slang/slang-check-decl.cpp
+++ b/source/slang/slang-check-decl.cpp
@@ -90,6 +90,10 @@ struct SemanticsDeclAttributesVisitor : public SemanticsDeclVisitorBase,
void checkPrimalSubstituteOfAttribute(
FunctionDeclBase* funcDecl,
PrimalSubstituteOfAttribute* attr);
+
+ void checkVarDeclCommon(VarDeclBase* varDecl);
+
+ void visitVarDecl(VarDecl* varDecl) { checkVarDeclCommon(varDecl); }
};
struct SemanticsDeclHeaderVisitor : public SemanticsDeclVisitorBase,
@@ -11712,6 +11716,43 @@ bool tryCheckDerivativeOfAttributeImpl(
return tempSink.getErrorCount() == 0;
}
+void SemanticsDeclAttributesVisitor::checkVarDeclCommon(VarDeclBase* varDecl)
+{
+ bool hasSpecConstAttr = false;
+ bool hasPushConstAttr = false;
+ for (auto modifier : varDecl->modifiers)
+ {
+ if (as<SpecializationConstantAttribute>(modifier) || as<VkConstantIdAttribute>(modifier))
+ {
+ // Specialization constant.
+ // Check that type is basic type.
+ if (!as<BasicExpressionType>(varDecl->getType()) && !as<ErrorType>(varDecl->getType()))
+ {
+ getSink()->diagnose(modifier, Diagnostics::specializationConstantMustBeScalar);
+ }
+ hasSpecConstAttr = true;
+ }
+ else if (as<PushConstantAttribute>(modifier))
+ {
+ hasPushConstAttr = true;
+ }
+ }
+ if (hasSpecConstAttr && hasPushConstAttr)
+ {
+ getSink()->diagnose(
+ varDecl,
+ Diagnostics::variableCannotBePushAndSpecializationConstant,
+ varDecl->getName());
+ }
+ if (hasSpecConstAttr || hasPushConstAttr)
+ {
+ if (varDecl->findModifier<HLSLStaticModifier>())
+ {
+ getSink()->diagnose(varDecl, Diagnostics::pushOrSpecializationConstantCannotBeStatic);
+ }
+ }
+}
+
void SemanticsDeclAttributesVisitor::checkForwardDerivativeOfAttribute(
FunctionDeclBase* funcDecl,
ForwardDerivativeOfAttribute* attr)
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index d6409e42e..305013f43 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -1213,8 +1213,21 @@ DIAGNOSTIC(
Error,
unrecognizedGLSLLayoutQualifierOrRequiresAssignment,
"GLSL layout qualifier is unrecognized or requires assignment")
-
-
+DIAGNOSTIC(
+ 31218,
+ Error,
+ specializationConstantMustBeScalar,
+ "specialization constant must be a scalar.")
+DIAGNOSTIC(
+ 31219,
+ Error,
+ pushOrSpecializationConstantCannotBeStatic,
+ "push or specialization constants cannot be 'static'.")
+DIAGNOSTIC(
+ 31220,
+ Error,
+ variableCannotBePushAndSpecializationConstant,
+ "'$0' cannot be a push constant and a specialization constant at the same time")
// Enums
DIAGNOSTIC(32000, Error, invalidEnumTagType, "invalid tag type for 'enum': '$0'")
diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp
index c232d0aee..7fb719053 100644
--- a/source/slang/slang-parameter-binding.cpp
+++ b/source/slang/slang-parameter-binding.cpp
@@ -3858,7 +3858,7 @@ static bool _calcNeedsDefaultSpace(SharedParameterBindingContext& sharedContext)
{
default:
break;
-
+ case LayoutResourceKind::PushConstantBuffer:
case LayoutResourceKind::RegisterSpace:
case LayoutResourceKind::SubElementRegisterSpace:
case LayoutResourceKind::VaryingInput:
diff --git a/tests/diagnostics/specialization-constants.slang b/tests/diagnostics/specialization-constants.slang
new file mode 100644
index 000000000..30f3a5f95
--- /dev/null
+++ b/tests/diagnostics/specialization-constants.slang
@@ -0,0 +1,16 @@
+//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+struct T { int x; int y; }
+
+// CHECK: ([[# @LINE+1]]): error 31218
+[vk::constant_id(1)]
+const T st;
+
+[vk::constant_id(1)]
+// CHECK: ([[# @LINE+1]]): error 31219
+static const int x = 2;
+
+[push_constant]
+[vk::constant_id(1)]
+// CHECK: ([[# @LINE+1]]): error 31220
+const int y; \ No newline at end of file
diff --git a/tests/spirv/push-constant-space.slang b/tests/spirv/push-constant-space.slang
new file mode 100644
index 000000000..847c60b7d
--- /dev/null
+++ b/tests/spirv/push-constant-space.slang
@@ -0,0 +1,18 @@
+// Test that push constants should not occupy the default
+// space.
+
+//TEST:SIMPLE(filecheck=CHECK): -target spirv
+
+// CHECK-NOT: OpDecorate {{.*}} DescriptorSet 1
+
+struct Data {
+ StructuredBuffer<uint4> data;
+ RWStructuredBuffer<float> output;
+};
+ParameterBlock<Data> gData;
+
+[numthreads(1,1,1)]
+void taskMain(uniform uint a)
+{
+ gData.output[0] = gData.data[0].x + a;
+}