diff options
| author | Yong He <yonghe@outlook.com> | 2024-12-17 22:30:22 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-17 22:30:22 -0800 |
| commit | 45af2467289bd39baff0269bb7de8a538f617dec (patch) | |
| tree | de45c041f03d0e6b8d72235edbee7b7671220c0c | |
| parent | 6e24244832d9032f0993cb088af625238096b723 (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.cpp | 41 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 17 | ||||
| -rw-r--r-- | source/slang/slang-parameter-binding.cpp | 2 | ||||
| -rw-r--r-- | tests/diagnostics/specialization-constants.slang | 16 | ||||
| -rw-r--r-- | tests/spirv/push-constant-space.slang | 18 |
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; +} |
