Skip to content

Commit

Permalink
Add verification logic on push and specialization constants.
Browse files Browse the repository at this point in the history
  • Loading branch information
csyonghe committed Dec 16, 2024
1 parent 0a6ffee commit 00d1035
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 3 deletions.
39 changes: 39 additions & 0 deletions source/slang/slang-check-decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -11712,6 +11716,41 @@ 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)
Expand Down
17 changes: 15 additions & 2 deletions source/slang/slang-diagnostic-defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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'")
Expand Down
2 changes: 1 addition & 1 deletion source/slang/slang-parameter-binding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3858,7 +3858,7 @@ static bool _calcNeedsDefaultSpace(SharedParameterBindingContext& sharedContext)
{
default:
break;

case LayoutResourceKind::PushConstantBuffer:
case LayoutResourceKind::RegisterSpace:
case LayoutResourceKind::SubElementRegisterSpace:
case LayoutResourceKind::VaryingInput:
Expand Down
16 changes: 16 additions & 0 deletions tests/diagnostics/specialization-constants.slang
Original file line number Diff line number Diff line change
@@ -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;
18 changes: 18 additions & 0 deletions tests/spirv/push-constant-space.slang
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 00d1035

Please sign in to comment.