Reject constant_id on a specialization constant computed from others Such a constant is emitted as an OpSpecConstantOp, which SPIR-V does not allow a SpecId decoration on, so the module failed validation. Test/spv.int64.frag declared one and its baseline recorded the validation failure.
diff --git a/Test/baseResults/spv.int64.frag.out b/Test/baseResults/spv.int64.frag.out index 84c4ff9..a22b07d 100644 --- a/Test/baseResults/spv.int64.frag.out +++ b/Test/baseResults/spv.int64.frag.out
@@ -1,5 +1,4 @@ spv.int64.frag -Validation failed // Module Version 10000 // Generated by (magic number): 8000b // Id's are bound by 516 @@ -85,7 +84,6 @@ Decorate 491(si) SpecId 102 Decorate 492(su) SpecId 103 Decorate 493(sb) SpecId 104 - Decorate 494(su64inc) SpecId 105 2: TypeVoid 3: TypeFunction 2 14: TypeInt 64 0
diff --git a/Test/baseResults/validation_fails.txt b/Test/baseResults/validation_fails.txt index f2e7cf4..f932e36 100644 --- a/Test/baseResults/validation_fails.txt +++ b/Test/baseResults/validation_fails.txt
@@ -68,7 +68,6 @@ Test/baseResults/spv.functionNestedOpaque.vert.out Test/baseResults/spv.imageAtomic64.frag.out Test/baseResults/spv.image.frag.out -Test/baseResults/spv.int64.frag.out Test/baseResults/spv.memoryQualifier.frag.out Test/baseResults/spv.newTexture.frag.out Test/baseResults/spv.nvgpushader5.frag.out
diff --git a/Test/baseResults/vulkan.vert.out b/Test/baseResults/vulkan.vert.out index 5643411..74437d4 100644 --- a/Test/baseResults/vulkan.vert.out +++ b/Test/baseResults/vulkan.vert.out
@@ -53,7 +53,8 @@ ERROR: 0:77: 'constant_id' : needs a literal integer ERROR: 0:77: 'constant_id' : can only be applied to 'const'-qualified scalar ERROR: 0:77: 'constant_id' : can only be applied to a scalar -ERROR: 54 compilation errors. No code generated. +ERROR: 0:80: 'constant_id' : cannot be applied to a constant computed from other specialization constants +ERROR: 55 compilation errors. No code generated. SPIR-V is not generated for failed compile or link
diff --git a/Test/spv.int64.frag b/Test/spv.int64.frag index 0f80d55..84a7e2b 100644 --- a/Test/spv.int64.frag +++ b/Test/spv.int64.frag
@@ -244,7 +244,7 @@ layout(constant_id = 102) const int si = -5; layout(constant_id = 103) const uint su = 4; layout(constant_id = 104) const bool sb = true; -layout(constant_id = 105) const uint64_t su64inc = su64 + 1UL; +const uint64_t su64inc = su64 + 1UL; // bool <-> int64/uint64 const bool i64_to_b = bool(si64);
diff --git a/Test/vulkan.vert b/Test/vulkan.vert index 269b920..8787603 100644 --- a/Test/vulkan.vert +++ b/Test/vulkan.vert
@@ -75,3 +75,6 @@ } nonLitBI; layout(input_attachment_index = nonLit) vec4 nonLit3; // ERROR, non literal layout(constant_id = nonLit) vec4 nonLit4; // ERROR, non literal + +layout(constant_id = 18) const int c3 = 12; +layout(constant_id = 19) const int c4 = c3 + 1; // ERROR, computed from another spec constant
diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 92b3468..0e44577 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -10328,6 +10328,10 @@ variable->setConstArray(initializer->getAsConstantUnion()->getConstArray()); else { // It's a specialization constant. + // Computed from other spec constants, so it becomes an OpSpecConstantOp, which cannot carry SpecId. + if (variable->getType().getQualifier().hasSpecConstantId()) + error(loc, "cannot be applied to a constant computed from other specialization constants", + "constant_id", ""); variable->getWritableType().getQualifier().makeSpecConstant(); // Keep the subtree that computes the specialization constant with the variable.