Generate SPV_EXT_replicated_composites when requested by pragma.

Implement GL_EXT_spec_constant_composites.
This commit is contained in:
Jeff Bolz 2024-05-31 12:00:03 -05:00 committed by arcady-lunarg
parent 6a8b2b2439
commit 4da479aa6a
19 changed files with 656 additions and 14 deletions

View File

@ -61,5 +61,6 @@ static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_coope
static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence"; static const char* const E_SPV_KHR_maximal_reconvergence = "SPV_KHR_maximal_reconvergence";
static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate"; static const char* const E_SPV_KHR_subgroup_rotate = "SPV_KHR_subgroup_rotate";
static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume"; static const char* const E_SPV_KHR_expect_assume = "SPV_KHR_expect_assume";
static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_replicated_composites";
#endif // #ifndef GLSLextKHR_H #endif // #ifndef GLSLextKHR_H

View File

@ -1583,6 +1583,8 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
builder.addInclude(iItr->first, iItr->second); builder.addInclude(iItr->first, iItr->second);
} }
builder.setUseReplicatedComposites(glslangIntermediate->usingReplicatedComposites());
stdBuiltins = builder.import("GLSL.std.450"); stdBuiltins = builder.import("GLSL.std.450");
spv::AddressingModel addressingModel = spv::AddressingModelLogical; spv::AddressingModel addressingModel = spv::AddressingModelLogical;

View File

@ -1484,12 +1484,14 @@ bool Builder::isConstantOpCode(Op opcode) const
case OpConstantFalse: case OpConstantFalse:
case OpConstant: case OpConstant:
case OpConstantComposite: case OpConstantComposite:
case OpConstantCompositeReplicateEXT:
case OpConstantSampler: case OpConstantSampler:
case OpConstantNull: case OpConstantNull:
case OpSpecConstantTrue: case OpSpecConstantTrue:
case OpSpecConstantFalse: case OpSpecConstantFalse:
case OpSpecConstant: case OpSpecConstant:
case OpSpecConstantComposite: case OpSpecConstantComposite:
case OpSpecConstantCompositeReplicateEXT:
case OpSpecConstantOp: case OpSpecConstantOp:
return true; return true;
default: default:
@ -1506,6 +1508,7 @@ bool Builder::isSpecConstantOpCode(Op opcode) const
case OpSpecConstant: case OpSpecConstant:
case OpSpecConstantComposite: case OpSpecConstantComposite:
case OpSpecConstantOp: case OpSpecConstantOp:
case OpSpecConstantCompositeReplicateEXT:
return true; return true;
default: default:
return false; return false;
@ -1782,10 +1785,27 @@ Id Builder::findStructConstant(Id typeId, const std::vector<Id>& comps)
// Comments in header // Comments in header
Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, bool specConstant) Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, bool specConstant)
{ {
Op opcode = specConstant ? OpSpecConstantComposite : OpConstantComposite;
assert(typeId); assert(typeId);
Op typeClass = getTypeClass(typeId); Op typeClass = getTypeClass(typeId);
bool replicate = false;
size_t numMembers = members.size();
if (useReplicatedComposites) {
// use replicate if all members are the same
replicate = numMembers > 0 &&
std::equal(members.begin() + 1, members.end(), members.begin());
if (replicate) {
numMembers = 1;
addCapability(spv::CapabilityReplicatedCompositesEXT);
addExtension(spv::E_SPV_EXT_replicated_composites);
}
}
Op opcode = replicate ?
(specConstant ? OpSpecConstantCompositeReplicateEXT : OpConstantCompositeReplicateEXT) :
(specConstant ? OpSpecConstantComposite : OpConstantComposite);
switch (typeClass) { switch (typeClass) {
case OpTypeVector: case OpTypeVector:
case OpTypeArray: case OpTypeArray:
@ -1812,7 +1832,7 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, boo
Instruction* c = new Instruction(getUniqueId(), typeId, opcode); Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
c->reserveOperands(members.size()); c->reserveOperands(members.size());
for (int op = 0; op < (int)members.size(); ++op) for (size_t op = 0; op < numMembers; ++op)
c->addIdOperand(members[op]); c->addIdOperand(members[op]);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c)); constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(c));
if (typeClass == OpTypeStruct) if (typeClass == OpTypeStruct)
@ -2928,7 +2948,17 @@ Id Builder::smearScalar(Decoration precision, Id scalar, Id vectorType)
auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar)); auto result_id = makeCompositeConstant(vectorType, members, isSpecConstant(scalar));
smear = module.getInstruction(result_id); smear = module.getInstruction(result_id);
} else { } else {
smear = new Instruction(getUniqueId(), vectorType, OpCompositeConstruct); bool replicate = useReplicatedComposites && (numComponents > 0);
if (replicate) {
numComponents = 1;
addCapability(spv::CapabilityReplicatedCompositesEXT);
addExtension(spv::E_SPV_EXT_replicated_composites);
}
Op opcode = replicate ? OpCompositeConstructReplicateEXT : OpCompositeConstruct;
smear = new Instruction(getUniqueId(), vectorType, opcode);
smear->reserveOperands(numComponents); smear->reserveOperands(numComponents);
for (int c = 0; c < numComponents; ++c) for (int c = 0; c < numComponents; ++c)
smear->addIdOperand(scalar); smear->addIdOperand(scalar);
@ -3321,9 +3351,25 @@ Id Builder::createCompositeConstruct(Id typeId, const std::vector<Id>& constitue
[&](spv::Id id) { return isSpecConstant(id); })); [&](spv::Id id) { return isSpecConstant(id); }));
} }
Instruction* op = new Instruction(getUniqueId(), typeId, OpCompositeConstruct); bool replicate = false;
size_t numConstituents = constituents.size();
if (useReplicatedComposites) {
replicate = numConstituents > 0 &&
std::equal(constituents.begin() + 1, constituents.end(), constituents.begin());
}
if (replicate) {
numConstituents = 1;
addCapability(spv::CapabilityReplicatedCompositesEXT);
addExtension(spv::E_SPV_EXT_replicated_composites);
}
Op opcode = replicate ? OpCompositeConstructReplicateEXT : OpCompositeConstruct;
Instruction* op = new Instruction(getUniqueId(), typeId, opcode);
op->reserveOperands(constituents.size()); op->reserveOperands(constituents.size());
for (int c = 0; c < (int)constituents.size(); ++c) for (size_t c = 0; c < numConstituents; ++c)
op->addIdOperand(constituents[c]); op->addIdOperand(constituents[c]);
addInstruction(std::unique_ptr<Instruction>(op)); addInstruction(std::unique_ptr<Instruction>(op));
@ -3458,6 +3504,13 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision); return setPrecision(createCompositeConstruct(resultTypeId, matrixColumns), precision);
} }
// Detect a matrix being constructed from a repeated vector of the correct size.
// Create the composite directly from it.
if ((int)sources.size() == numCols && isVector(sources[0]) && getNumComponents(sources[0]) == numRows &&
std::equal(sources.begin() + 1, sources.end(), sources.begin())) {
return setPrecision(createCompositeConstruct(resultTypeId, sources), precision);
}
// Otherwise, will use a two step process // Otherwise, will use a two step process
// 1. make a compile-time 2D array of values // 1. make a compile-time 2D array of values
// 2. construct a matrix from that array // 2. construct a matrix from that array

View File

@ -872,6 +872,8 @@ public:
// Check if the builder is generating code for spec constants. // Check if the builder is generating code for spec constants.
bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; } bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }
void setUseReplicatedComposites(bool use) { useReplicatedComposites = use; }
protected: protected:
Id makeIntConstant(Id typeId, unsigned value, bool specConstant); Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant); Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
@ -938,6 +940,7 @@ public:
Id uniqueId; Id uniqueId;
Function* entryPointFunction; Function* entryPointFunction;
bool generatingOpCodeForSpecConst; bool generatingOpCodeForSpecConst;
bool useReplicatedComposites { false };
AccessChain accessChain; AccessChain accessChain;
// special blocks of instructions for output // special blocks of instructions for output

View File

@ -1066,6 +1066,8 @@ const char* CapabilityString(int info)
case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM";
case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM"; case CapabilityTextureBlockMatch2QCOM: return "TextureBlockMatch2QCOM";
case CapabilityReplicatedCompositesEXT: return "CapabilityReplicatedCompositesEXT";
default: return "Bad"; default: return "Bad";
} }
} }
@ -1584,6 +1586,10 @@ const char* OpcodeString(int op)
case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM"; case OpImageBlockMatchGatherSSDQCOM: return "OpImageBlockMatchGatherSSDQCOM";
case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM"; case OpImageBlockMatchGatherSADQCOM: return "OpImageBlockMatchGatherSADQCOM";
case OpConstantCompositeReplicateEXT: return "OpConstantCompositeReplicateEXT";
case OpSpecConstantCompositeReplicateEXT: return "OpSpecConstantCompositeReplicateEXT";
case OpCompositeConstructReplicateEXT: return "OpCompositeConstructReplicateEXT";
default: default:
return "Bad"; return "Bad";
} }
@ -3471,6 +3477,10 @@ void Parameterize()
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'block size'"); InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandId, "'block size'");
InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandImageOperands, "", true); InstructionDesc[OpImageBlockMatchGatherSADQCOM].operands.push(OperandImageOperands, "", true);
InstructionDesc[OpImageBlockMatchGatherSADQCOM].setResultAndType(true, true); InstructionDesc[OpImageBlockMatchGatherSADQCOM].setResultAndType(true, true);
InstructionDesc[OpConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpSpecConstantCompositeReplicateEXT].operands.push(OperandId, "'Value'");
InstructionDesc[OpCompositeConstructReplicateEXT].operands.push(OperandId, "'Value'");
}); });
} }

View File

@ -1162,7 +1162,8 @@ enum Capability {
CapabilityDotProduct = 6019, CapabilityDotProduct = 6019,
CapabilityDotProductKHR = 6019, CapabilityDotProductKHR = 6019,
CapabilityRayCullMaskKHR = 6020, CapabilityRayCullMaskKHR = 6020,
CapabilityCooperativeMatrixKHR = 6022, CapabilityCooperativeMatrixKHR = 6022,
CapabilityReplicatedCompositesEXT = 6024,
CapabilityBitInstructions = 6025, CapabilityBitInstructions = 6025,
CapabilityGroupNonUniformRotateKHR = 6026, CapabilityGroupNonUniformRotateKHR = 6026,
CapabilityAtomicFloat32AddEXT = 6033, CapabilityAtomicFloat32AddEXT = 6033,
@ -1688,7 +1689,10 @@ enum Op {
OpCooperativeMatrixLoadKHR = 4457, OpCooperativeMatrixLoadKHR = 4457,
OpCooperativeMatrixStoreKHR = 4458, OpCooperativeMatrixStoreKHR = 4458,
OpCooperativeMatrixMulAddKHR = 4459, OpCooperativeMatrixMulAddKHR = 4459,
OpCooperativeMatrixLengthKHR = 4460, OpCooperativeMatrixLengthKHR = 4460,
OpConstantCompositeReplicateEXT = 4461,
OpSpecConstantCompositeReplicateEXT = 4462,
OpCompositeConstructReplicateEXT = 4463,
OpTypeRayQueryKHR = 4472, OpTypeRayQueryKHR = 4472,
OpRayQueryInitializeKHR = 4473, OpRayQueryInitializeKHR = 4473,
OpRayQueryTerminateKHR = 4474, OpRayQueryTerminateKHR = 4474,
@ -2417,7 +2421,10 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) {
case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break;
case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break;
case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break;
case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break;
case OpConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpSpecConstantCompositeReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpCompositeConstructReplicateEXT: *hasResult = true; *hasResultType = true; break;
case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break;
case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break;
case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break;

View File

@ -0,0 +1,117 @@
spv.replicate.comp
// Module Version 10000
// Generated by (magic number): 8000b
// Id's are bound by 66
Capability Shader
Capability VulkanMemoryModelKHR
Capability CooperativeMatrixKHR
Capability CapabilityReplicatedCompositesEXT
Extension "SPV_EXT_replicated_composites"
Extension "SPV_KHR_cooperative_matrix"
Extension "SPV_KHR_vulkan_memory_model"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical VulkanKHR
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 1 1 1
Source GLSL 450
SourceExtension "GL_EXT_spec_constant_composites"
SourceExtension "GL_KHR_cooperative_matrix"
SourceExtension "GL_KHR_memory_scope_semantics"
Name 4 "main"
Name 13 "coop"
Name 17 "a"
Name 21 "v"
Name 28 "m"
Name 33 "five"
Name 35 "six"
Name 39 "arr"
Name 44 "arr2"
Name 49 "S"
MemberName 49(S) 0 "a"
MemberName 49(S) 1 "b"
MemberName 49(S) 2 "c"
Name 51 "s2"
Name 54 "SS"
MemberName 54(SS) 0 "s1"
MemberName 54(SS) 1 "s2"
Name 56 "ss"
Decorate 61 BuiltIn WorkgroupSize
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeInt 32 0
8: 7(int) Constant 3
9: 7(int) Constant 16
10: 7(int) Constant 0
11: TypeCooperativeMatrixKHR 6(float) 8 9 9 10
12: TypePointer Function 11
14: 6(float) Constant 1065353216
15: 11 ConstantCompositeReplicateEXT 14
16: TypePointer Function 6(float)
18: 6(float) Constant 1073741824
19: TypeVector 6(float) 4
20: TypePointer Function 19(fvec4)
24: 6(float) Constant 1077936128
25: 19(fvec4) ConstantCompositeReplicateEXT 24
26: TypeMatrix 19(fvec4) 4
27: TypePointer Function 26
31: TypeInt 32 1
32: TypePointer Function 31(int)
34: 31(int) Constant 5
36: 31(int) Constant 6
37: TypeArray 31(int) 8
38: TypePointer Function 37
42: TypeArray 37 8
43: TypePointer Function 42
47: 37 ConstantCompositeReplicateEXT 34
48: 42 ConstantCompositeReplicateEXT 47
49(S): TypeStruct 31(int) 31(int) 31(int)
50: TypePointer Function 49(S)
54(SS): TypeStruct 49(S) 49(S)
55: TypePointer Function 54(SS)
59: TypeVector 7(int) 3
60: 7(int) Constant 1
61: 59(ivec3) ConstantCompositeReplicateEXT 60
62: 49(S) ConstantCompositeReplicateEXT 36
63: 54(SS) ConstantCompositeReplicateEXT 62
64: 26 ConstantCompositeReplicateEXT 25
65: 11 ConstantCompositeReplicateEXT 24
4(main): 2 Function None 3
5: Label
13(coop): 12(ptr) Variable Function
17(a): 16(ptr) Variable Function
21(v): 20(ptr) Variable Function
28(m): 27(ptr) Variable Function
33(five): 32(ptr) Variable Function
35(six): 32(ptr) Variable Function
39(arr): 38(ptr) Variable Function
44(arr2): 43(ptr) Variable Function
51(s2): 50(ptr) Variable Function
56(ss): 55(ptr) Variable Function
Store 13(coop) 15
Store 17(a) 18
22: 6(float) Load 17(a)
23: 19(fvec4) CompositeConstructReplicateEXT 22
Store 21(v) 23
Store 21(v) 25
29: 19(fvec4) Load 21(v)
30: 26 CompositeConstructReplicateEXT 29
Store 28(m) 30
Store 33(five) 34
Store 35(six) 36
40: 31(int) Load 33(five)
41: 37 CompositeConstructReplicateEXT 40
Store 39(arr) 41
45: 37 Load 39(arr)
46: 42 CompositeConstructReplicateEXT 45
Store 44(arr2) 46
Store 44(arr2) 48
52: 31(int) Load 35(six)
53: 49(S) CompositeConstructReplicateEXT 52
Store 51(s2) 53
57: 49(S) Load 51(s2)
58: 54(SS) CompositeConstructReplicateEXT 57
Store 56(ss) 58
Return
FunctionEnd

View File

@ -0,0 +1,132 @@
spv.replicatespec.comp
// Module Version 10000
// Generated by (magic number): 8000b
// Id's are bound by 68
Capability Shader
Capability VulkanMemoryModelKHR
Capability CooperativeMatrixKHR
Capability CapabilityReplicatedCompositesEXT
Extension "SPV_EXT_replicated_composites"
Extension "SPV_KHR_cooperative_matrix"
Extension "SPV_KHR_vulkan_memory_model"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical VulkanKHR
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 1 1 1
Source GLSL 450
SourceExtension "GL_EXT_spec_constant_composites"
SourceExtension "GL_KHR_cooperative_matrix"
SourceExtension "GL_KHR_memory_scope_semantics"
Name 4 "main"
Name 13 "coop"
Name 17 "a"
Name 21 "v"
Name 24 "spec_float"
Name 25 "cv"
Name 28 "m"
Name 33 "five"
Name 35 "six"
Name 39 "arr"
Name 44 "arr2"
Name 47 "cfive"
Name 48 "carr"
Name 49 "carr2"
Name 50 "S"
MemberName 50(S) 0 "a"
MemberName 50(S) 1 "b"
MemberName 50(S) 2 "c"
Name 52 "s2"
Name 55 "SS"
MemberName 55(SS) 0 "s1"
MemberName 55(SS) 1 "s2"
Name 57 "ss"
Name 63 "csix"
Name 64 "cs"
Name 65 "css"
Name 66 "cm"
Name 67 "ccoop"
Decorate 24(spec_float) SpecId 2
Decorate 47(cfive) SpecId 0
Decorate 62 BuiltIn WorkgroupSize
Decorate 63(csix) SpecId 1
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeInt 32 0
8: 7(int) Constant 3
9: 7(int) Constant 16
10: 7(int) Constant 0
11: TypeCooperativeMatrixKHR 6(float) 8 9 9 10
12: TypePointer Function 11
14: 6(float) Constant 1065353216
15: 11 ConstantCompositeReplicateEXT 14
16: TypePointer Function 6(float)
18: 6(float) Constant 1073741824
19: TypeVector 6(float) 4
20: TypePointer Function 19(fvec4)
24(spec_float): 6(float) SpecConstant 1077936128
25(cv): 19(fvec4) SpecConstantCompositeReplicateEXT 24(spec_float)
26: TypeMatrix 19(fvec4) 4
27: TypePointer Function 26
31: TypeInt 32 1
32: TypePointer Function 31(int)
34: 31(int) Constant 5
36: 31(int) Constant 6
37: TypeArray 31(int) 8
38: TypePointer Function 37
42: TypeArray 37 8
43: TypePointer Function 42
47(cfive): 31(int) SpecConstant 5
48(carr): 37 SpecConstantCompositeReplicateEXT 47(cfive)
49(carr2): 42 SpecConstantCompositeReplicateEXT 48(carr)
50(S): TypeStruct 31(int) 31(int) 31(int)
51: TypePointer Function 50(S)
55(SS): TypeStruct 50(S) 50(S)
56: TypePointer Function 55(SS)
60: TypeVector 7(int) 3
61: 7(int) Constant 1
62: 60(ivec3) ConstantCompositeReplicateEXT 61
63(csix): 31(int) SpecConstant 6
64(cs): 50(S) SpecConstantCompositeReplicateEXT 63(csix)
65(css): 55(SS) SpecConstantCompositeReplicateEXT 64(cs)
66(cm): 26 SpecConstantCompositeReplicateEXT 25(cv)
67(ccoop): 11 SpecConstantCompositeReplicateEXT 24(spec_float)
4(main): 2 Function None 3
5: Label
13(coop): 12(ptr) Variable Function
17(a): 16(ptr) Variable Function
21(v): 20(ptr) Variable Function
28(m): 27(ptr) Variable Function
33(five): 32(ptr) Variable Function
35(six): 32(ptr) Variable Function
39(arr): 38(ptr) Variable Function
44(arr2): 43(ptr) Variable Function
52(s2): 51(ptr) Variable Function
57(ss): 56(ptr) Variable Function
Store 13(coop) 15
Store 17(a) 18
22: 6(float) Load 17(a)
23: 19(fvec4) CompositeConstructReplicateEXT 22
Store 21(v) 23
Store 21(v) 25(cv)
29: 19(fvec4) Load 21(v)
30: 26 CompositeConstructReplicateEXT 29
Store 28(m) 30
Store 33(five) 34
Store 35(six) 36
40: 31(int) Load 33(five)
41: 37 CompositeConstructReplicateEXT 40
Store 39(arr) 41
45: 37 Load 39(arr)
46: 42 CompositeConstructReplicateEXT 45
Store 44(arr2) 46
Store 44(arr2) 49(carr2)
53: 31(int) Load 35(six)
54: 50(S) CompositeConstructReplicateEXT 53
Store 52(s2) 54
58: 50(S) Load 52(s2)
59: 55(SS) CompositeConstructReplicateEXT 58
Store 57(ss) 59
Return
FunctionEnd

View File

@ -0,0 +1,89 @@
spv.specConstantComposite2.vert
// Module Version 10000
// Generated by (magic number): 8000b
// Id's are bound by 43
Capability Shader
Capability Float64
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Vertex 4 "main" 27 42
Source GLSL 450
Name 4 "main"
Name 6 "refer_primary_spec_const("
Name 8 "refer_composite_spec_const("
Name 10 "refer_copmosite_dot_dereference("
Name 12 "refer_composite_bracket_dereference("
Name 16 "refer_spec_const_array_length("
Name 18 "declare_spec_const_in_func("
Name 21 "spec_bool"
Name 27 "color"
Name 28 "spec_int"
Name 33 "len"
Name 37 "spec_float"
Name 39 "spec_double"
Name 42 "global_vec4_array_with_spec_length"
Decorate 21(spec_bool) SpecId 203
Decorate 27(color) Location 0
Decorate 28(spec_int) SpecId 200
Decorate 37(spec_float) SpecId 201
Decorate 39(spec_double) SpecId 202
Decorate 42(global_vec4_array_with_spec_length) Location 0
2: TypeVoid
3: TypeFunction 2
14: TypeInt 32 1
15: TypeFunction 14(int)
20: TypeBool
21(spec_bool): 20(bool) SpecConstantTrue
24: TypeFloat 32
25: TypeVector 24(float) 4
26: TypePointer Output 25(fvec4)
27(color): 26(ptr) Variable Output
28(spec_int): 14(int) SpecConstant 3
32: TypePointer Function 14(int)
37(spec_float): 24(float) SpecConstant 1078523331
38: TypeFloat 64
39(spec_double):38(float64_t) SpecConstant 1413754136 1074340347
40: TypeArray 25(fvec4) 28(spec_int)
41: TypePointer Input 40
42(global_vec4_array_with_spec_length): 41(ptr) Variable Input
4(main): 2 Function None 3
5: Label
Return
FunctionEnd
6(refer_primary_spec_const(): 2 Function None 3
7: Label
SelectionMerge 23 None
BranchConditional 21(spec_bool) 22 23
22: Label
29: 24(float) ConvertSToF 28(spec_int)
30: 25(fvec4) Load 27(color)
31: 25(fvec4) VectorTimesScalar 30 29
Store 27(color) 31
Branch 23
23: Label
Return
FunctionEnd
8(refer_composite_spec_const(): 2 Function None 3
9: Label
Return
FunctionEnd
10(refer_copmosite_dot_dereference(): 2 Function None 3
11: Label
Return
FunctionEnd
12(refer_composite_bracket_dereference(): 2 Function None 3
13: Label
Return
FunctionEnd
16(refer_spec_const_array_length(): 14(int) Function None 15
17: Label
33(len): 32(ptr) Variable Function
Store 33(len) 28(spec_int)
34: 14(int) Load 33(len)
ReturnValue 34
FunctionEnd
18(declare_spec_const_in_func(): 2 Function None 3
19: Label
Return
FunctionEnd

43
Test/spv.replicate.comp Normal file
View File

@ -0,0 +1,43 @@
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_KHR_cooperative_matrix : enable
#extension GL_EXT_spec_constant_composites : enable
#pragma use_replicated_composites
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
const int csix = 6;
struct S { int a; int b; int c; };
struct SS { S s1; S s2; };
const S cs = S(csix, csix, csix);
const SS css = SS(cs, cs);
const float spec_float = 3;
const vec4 cv = vec4(spec_float);
const mat4 cm = mat4(cv,cv,cv,cv);
const int cfive = 5;
const int carr[3] = {cfive, cfive, cfive};
const int carr2[3][3] = {carr, carr, carr};
const coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA> ccoop = coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA>(spec_float);
void main()
{
coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA> coop = coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA>(1.0);
float a = 2.0;
vec4 v = vec4(a);
v = cv;
mat4 m = mat4(v,v,v,v);
int five = 5;
int six = 6;
int arr[3] = {five, five, five};
int arr2[3][3] = {arr, arr, arr};
arr2 = carr2;
S s2 = S(six, six, six);
SS ss = SS(s2, s2);
}

View File

@ -0,0 +1,43 @@
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_KHR_cooperative_matrix : enable
#extension GL_EXT_spec_constant_composites : enable
#pragma use_replicated_composites
layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(constant_id = 1) const int csix = 6;
struct S { int a; int b; int c; };
struct SS { S s1; S s2; };
const S cs = S(csix, csix, csix);
const SS css = SS(cs, cs);
layout(constant_id = 2) const float spec_float = 3;
const vec4 cv = vec4(spec_float);
const mat4 cm = mat4(cv,cv,cv,cv);
layout(constant_id = 0) const int cfive = 5;
const int carr[3] = {cfive, cfive, cfive};
const int carr2[3][3] = {carr, carr, carr};
const coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA> ccoop = coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA>(spec_float);
void main()
{
coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA> coop = coopmat<float, gl_ScopeSubgroup, 16, 16, gl_MatrixUseA>(1.0);
float a = 2.0;
vec4 v = vec4(a);
v = cv;
mat4 m = mat4(v,v,v,v);
int five = 5;
int six = 6;
int arr[3] = {five, five, five};
int arr2[3][3] = {arr, arr, arr};
arr2 = carr2;
S s2 = S(six, six, six);
SS ss = SS(s2, s2);
}

View File

@ -0,0 +1,98 @@
#version 450
// constant_id specified scalar spec constants
layout(constant_id = 200) const int spec_int = 3;
layout(constant_id = 201) const float spec_float = 3.14;
layout(constant_id = 202) const
double spec_double = 3.1415926535897932384626433832795;
layout(constant_id = 203) const bool spec_bool = true;
// const float cast_spec_float = float(spec_float);
// Flat struct
struct flat_struct {
int i;
float f;
double d;
bool b;
};
// Nesting struct
struct nesting_struct {
flat_struct nested;
vec4 v;
int i;
};
// Expect OpSpecConstantComposite
// Flat struct initializer
//const flat_struct spec_flat_struct_all_spec = {spec_int, spec_float,
// spec_double, spec_bool};
//const flat_struct spec_flat_struct_partial_spec = {30, 30.14, spec_double,
// spec_bool};
// Nesting struct initializer
//const nesting_struct nesting_struct_ctor = {
// {spec_int, spec_float, spec_double, false},
// vec4(0.1, 0.1, 0.1, 0.1),
// spec_int};
// Vector constructor
//const vec4 spec_vec4_all_spec =
// vec4(spec_float, spec_float, spec_float, spec_float);
//const vec4 spec_vec4_partial_spec =
// vec4(spec_float, spec_float, 300.14, 300.14);
//const vec4 spec_vec4_from_one_scalar = vec4(spec_float);
// Matrix constructor
//const mat2x3 spec_mat2x3 = mat2x3(spec_float, spec_float, spec_float, 1.1, 2.2, 3.3);
//const mat2x3 spec_mat2x3_from_one_scalar = mat2x3(spec_float);
// Struct nesting constructor
//const nesting_struct spec_nesting_struct_all_spec = {
// spec_flat_struct_all_spec, spec_vec4_all_spec, spec_int};
//const nesting_struct spec_nesting_struct_partial_spec = {
// spec_flat_struct_partial_spec, spec_vec4_partial_spec, 3000};
//const float spec_float_array[5] = {spec_float, spec_float, 1.0, 2.0, 3.0};
//const int spec_int_array[5] = {spec_int, spec_int, 1, 2, 30};
// global_vec4_array_with_spec_length is not a spec constant, but its array
// size is. When calling global_vec4_array_with_spec_length.length(), A
// TIntermSymbol Node should be returned, instead of a TIntermConstantUnion
// node which represents a known constant value.
in vec4 global_vec4_array_with_spec_length[spec_int];
out vec4 color;
void refer_primary_spec_const() {
if (spec_bool) color *= spec_int;
}
void refer_composite_spec_const() {
//color += spec_vec4_all_spec;
//color -= spec_vec4_partial_spec;
}
void refer_copmosite_dot_dereference() {
//color *= spec_nesting_struct_all_spec.i;
//color += spec_vec4_all_spec.x;
}
void refer_composite_bracket_dereference() {
//color -= spec_float_array[1];
//color /= spec_int_array[spec_int_array[spec_int]];
}
int refer_spec_const_array_length() {
int len = global_vec4_array_with_spec_length.length();
return len;
}
void declare_spec_const_in_func() {
//const nesting_struct spec_const_declared_in_func = {
// spec_flat_struct_partial_spec, spec_vec4_partial_spec, 10};
//color /= spec_const_declared_in_func.i;
}
void main() {}

View File

@ -38,5 +38,5 @@ void main()
ivec2[2](ivec2(sci2, sci2), ivec2(sci2, sci2)); // not a spec-const ivec2[2](ivec2(sci2, sci2), ivec2(sci2, sci2)); // not a spec-const
vec2(scf1, scf1); // spec-const vec2(scf1, scf1); // spec-const
vec2[2](vec2(scf1, scf1), vec2(scf1, scf1)); // not a spec-const vec2[2](vec2(scf1, scf1), vec2(scf1, scf1)); // spec-const
} }

View File

@ -399,6 +399,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
if (spvVersion.spv < glslang::EShTargetSpv_1_3) if (spvVersion.spv < glslang::EShTargetSpv_1_3)
error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", ""); error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", "");
intermediate.setUseVariablePointers(); intermediate.setUseVariablePointers();
} else if (spvVersion.spv > 0 && tokens[0].compare("use_replicated_composites") == 0) {
if (tokens.size() != 1)
error(loc, "extra tokens", "#pragma", "");
intermediate.setReplicatedComposites();
} else if (tokens[0].compare("once") == 0) { } else if (tokens[0].compare("once") == 0) {
warn(loc, "not implemented", "#pragma once", ""); warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0) { } else if (tokens[0].compare("glslang_binary_double_output") == 0) {
@ -3613,6 +3617,19 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
makeSpecConst = ! intArgument && !type.isArray(); makeSpecConst = ! intArgument && !type.isArray();
break; break;
case EOpConstructCooperativeMatrixNV:
case EOpConstructCooperativeMatrixKHR:
case EOpConstructStruct:
{
const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites };
if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) {
makeSpecConst = true;
} else {
makeSpecConst = false;
}
}
break;
default: default:
// anything else wasn't white-listed in the spec as a conversion // anything else wasn't white-listed in the spec as a conversion
makeSpecConst = false; makeSpecConst = false;
@ -8355,6 +8372,11 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
int paramCount = 0; // keeps track of the constructor parameter number being checked int paramCount = 0; // keeps track of the constructor parameter number being checked
// We don't know "top down" whether type is a specialization constant,
// but a const becomes a specialization constant if any of its children are.
bool hasSpecConst = false;
bool isConstConstructor = true;
// for each parameter to the constructor call, check to see if the right type is passed or convert them // for each parameter to the constructor call, check to see if the right type is passed or convert them
// to the right type if possible (and allowed). // to the right type if possible (and allowed).
// for structure constructors, just check if the right type is passed, no conversion is allowed. // for structure constructors, just check if the right type is passed, no conversion is allowed.
@ -8367,13 +8389,24 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode*
else else
newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true); newNode = constructBuiltIn(type, op, (*p)->getAsTyped(), node->getLoc(), true);
if (newNode) if (newNode) {
*p = newNode; *p = newNode;
else if (!newNode->getType().getQualifier().isConstant())
isConstConstructor = false;
if (newNode->getType().getQualifier().isSpecConstant())
hasSpecConst = true;
} else
return nullptr; return nullptr;
} }
TIntermTyped *ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc); TIntermTyped* ret_node = intermediate.setAggregateOperator(aggrNode, op, type, loc);
const char *specConstantCompositeExt[] = { E_GL_EXT_spec_constant_composites };
if (checkExtensionsRequested(loc, 1, specConstantCompositeExt, "spec constant aggregate constructor")) {
if (isConstConstructor && hasSpecConst) {
ret_node->getWritableType().getQualifier().makeSpecConstant();
}
}
TIntermAggregate *agg_node = ret_node->getAsAggregate(); TIntermAggregate *agg_node = ret_node->getAsAggregate();
if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix())) if (agg_node && (agg_node->isVector() || agg_node->isArray() || agg_node->isMatrix()))

View File

@ -265,6 +265,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_expect_assume] = EBhDisable; extensionBehavior[E_GL_EXT_expect_assume] = EBhDisable;
extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable; extensionBehavior[E_GL_EXT_control_flow_attributes2] = EBhDisable;
extensionBehavior[E_GL_EXT_spec_constant_composites] = EBhDisable;
extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable; extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable;
@ -519,6 +520,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_fragment_shading_rate 1\n" "#define GL_EXT_fragment_shading_rate 1\n"
"#define GL_EXT_shared_memory_block 1\n" "#define GL_EXT_shared_memory_block 1\n"
"#define GL_EXT_shader_integer_mix 1\n" "#define GL_EXT_shader_integer_mix 1\n"
"#define GL_EXT_spec_constant_composites 1\n"
// GL_KHR_shader_subgroup // GL_KHR_shader_subgroup
"#define GL_KHR_shader_subgroup_basic 1\n" "#define GL_KHR_shader_subgroup_basic 1\n"

View File

@ -222,6 +222,7 @@ const char* const E_GL_EXT_texture_array = "GL_EXT_texture_ar
const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence"; const char* const E_GL_EXT_maximal_reconvergence = "GL_EXT_maximal_reconvergence";
const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume"; const char* const E_GL_EXT_expect_assume = "GL_EXT_expect_assume";
const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2"; const char* const E_GL_EXT_control_flow_attributes2 = "GL_EXT_control_flow_attributes2";
const char* const E_GL_EXT_spec_constant_composites = "GL_EXT_spec_constant_composites";
// Arrays of extensions for the above viewportEXTs duplications // Arrays of extensions for the above viewportEXTs duplications

View File

@ -729,6 +729,11 @@ public:
usePhysicalStorageBuffer = true; usePhysicalStorageBuffer = true;
} }
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; } bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setReplicatedComposites()
{
useReplicatedComposites = true;
}
bool usingReplicatedComposites() const { return useReplicatedComposites; }
void setUseVariablePointers() void setUseVariablePointers()
{ {
useVariablePointers = true; useVariablePointers = true;
@ -1242,6 +1247,7 @@ protected:
bool subgroupUniformControlFlow; bool subgroupUniformControlFlow;
bool maximallyReconverges; bool maximallyReconverges;
bool usePhysicalStorageBuffer; bool usePhysicalStorageBuffer;
bool useReplicatedComposites { false };
TSpirvRequirement* spirvRequirement; TSpirvRequirement* spirvRequirement;
TSpirvExecutionMode* spirvExecutionMode; TSpirvExecutionMode* spirvExecutionMode;

View File

@ -468,6 +468,8 @@ INSTANTIATE_TEST_SUITE_P(
"spv.prepost.frag", "spv.prepost.frag",
"spv.privateVariableTypes.frag", "spv.privateVariableTypes.frag",
"spv.qualifiers.vert", "spv.qualifiers.vert",
"spv.replicate.comp",
"spv.replicatespec.comp",
"spv.sample.frag", "spv.sample.frag",
"spv.sampleId.frag", "spv.sampleId.frag",
"spv.samplePosition.frag", "spv.samplePosition.frag",

View File

@ -5,14 +5,14 @@
"site" : "github", "site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools", "subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools", "subdir" : "External/spirv-tools",
"commit": "dd4b663e13c07fea4fbb3f70c1c91c86731099f7" "commit": "148c97f6876e427efd76d2328122c3075eab4b8f"
}, },
{ {
"name" : "spirv-tools/external/spirv-headers", "name" : "spirv-tools/external/spirv-headers",
"site" : "github", "site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers", "subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers", "subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "4f7b471f1a66b6d06462cd4ba57628cc0cd087d7" "commit" : "ea77f2a826bc820cb8f57f9b2a7c7eccb681c731"
}, },
{ {
"name": "googletest", "name": "googletest",