Implement GL_NV_cooperative_matrix

This commit is contained in:
Jeff Bolz 2019-02-19 13:10:32 -06:00
parent ec484527b6
commit 4605e2ed2b
37 changed files with 5630 additions and 4211 deletions

View File

@ -72,4 +72,7 @@ const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
//SPV_NV_shading_rate
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
//SPV_NV_cooperative_matrix
const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix";
#endif // #ifndef GLSLextNV_H

141
SPIRV/GlslangToSpv.cpp Executable file → Normal file
View File

@ -1330,6 +1330,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
}
builder.setMemoryModel(addressingModel, memoryModel);
if (glslangIntermediate->usingVariablePointers()) {
builder.addCapability(spv::CapabilityVariablePointers);
}
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
@ -1870,16 +1874,31 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
// So, this has to be block.lastMember.length().
// SPV wants "block" and member number as the operands, go get them.
spv::Id length;
if (node->getOperand()->getType().isCoopMat()) {
spec_constant_op_mode_setter.turnOnSpecConstantOpMode();
spv::Id typeId = convertGlslangToSpvType(node->getOperand()->getType());
assert(builder.isCooperativeMatrixType(typeId));
length = builder.createCooperativeMatrixLength(typeId);
} else {
glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft();
block->traverse(this);
unsigned int member = node->getOperand()->getAsBinaryNode()->getRight()->getAsConstantUnion()->getConstArray()[0].getUConst();
spv::Id length = builder.createArrayLength(builder.accessChainGetLValue(), member);
length = builder.createArrayLength(builder.accessChainGetLValue(), member);
}
// GLSL semantics say the result of .length() is an int, while SPIR-V says
// signedness must be 0. So, convert from SPIR-V unsigned back to GLSL's
// AST expectation of a signed result.
if (glslangIntermediate->getSource() == glslang::EShSourceGlsl)
if (glslangIntermediate->getSource() == glslang::EShSourceGlsl) {
if (builder.isInSpecConstCodeGenMode()) {
length = builder.createBinOp(spv::OpIAdd, builder.makeIntType(32), length, builder.makeIntConstant(0));
} else {
length = builder.createUnaryOp(spv::OpBitcast, builder.makeIntType(32), length);
}
}
builder.clearAccessChain();
builder.setAccessChainRValue(length);
@ -2222,6 +2241,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
case glslang::EOpConstructStruct:
case glslang::EOpConstructTextureSampler:
case glslang::EOpConstructReference:
case glslang::EOpConstructCooperativeMatrix:
{
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
std::vector<spv::Id> arguments;
@ -2229,7 +2249,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
spv::Id constructed;
if (node->getOp() == glslang::EOpConstructTextureSampler)
constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments);
else if (node->getOp() == glslang::EOpConstructStruct || node->getType().isArray()) {
else if (node->getOp() == glslang::EOpConstructStruct ||
node->getOp() == glslang::EOpConstructCooperativeMatrix ||
node->getType().isArray()) {
std::vector<spv::Id> constituents;
for (int c = 0; c < (int)arguments.size(); ++c)
constituents.push_back(arguments[c]);
@ -2347,6 +2369,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
noReturnValue = true;
break;
#endif
case glslang::EOpCooperativeMatrixLoad:
case glslang::EOpCooperativeMatrixStore:
noReturnValue = true;
break;
default:
break;
@ -2389,6 +2415,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
//
glslang::TIntermSequence& glslangOperands = node->getSequence();
std::vector<spv::Id> operands;
std::vector<spv::IdImmediate> memoryAccessOperands;
for (int arg = 0; arg < (int)glslangOperands.size(); ++arg) {
// special case l-value operands; there are just a few
bool lvalue = false;
@ -2445,6 +2472,14 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
if (arg >= 2)
lvalue = true;
break;
case glslang::EOpCooperativeMatrixLoad:
if (arg == 0 || arg == 1)
lvalue = true;
break;
case glslang::EOpCooperativeMatrixStore:
if (arg == 1)
lvalue = true;
break;
default:
break;
}
@ -2453,6 +2488,50 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
glslangOperands[0]->getAsBinaryNode()->getLeft()->traverse(this);
else
glslangOperands[arg]->traverse(this);
if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
node->getOp() == glslang::EOpCooperativeMatrixStore) {
if (arg == 1) {
// fold "element" parameter into the access chain
spv::Builder::AccessChain save = builder.getAccessChain();
builder.clearAccessChain();
glslangOperands[2]->traverse(this);
spv::Id elementId = accessChainLoad(glslangOperands[2]->getAsTyped()->getType());
builder.setAccessChain(save);
// Point to the first element of the array.
builder.accessChainPush(elementId, TranslateCoherent(glslangOperands[arg]->getAsTyped()->getType()),
getBufferReferenceAlignment(glslangOperands[arg]->getAsTyped()->getType()));
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
unsigned int alignment = builder.getAccessChain().alignment;
int memoryAccess = TranslateMemoryAccess(coherentFlags);
if (node->getOp() == glslang::EOpCooperativeMatrixLoad)
memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask;
if (node->getOp() == glslang::EOpCooperativeMatrixStore)
memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask;
if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) {
memoryAccess = (spv::MemoryAccessMask)(memoryAccess | spv::MemoryAccessAlignedMask);
}
memoryAccessOperands.push_back(spv::IdImmediate(false, memoryAccess));
if (memoryAccess & spv::MemoryAccessAlignedMask) {
memoryAccessOperands.push_back(spv::IdImmediate(false, alignment));
}
if (memoryAccess & (spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask)) {
memoryAccessOperands.push_back(spv::IdImmediate(true, builder.makeUintConstant(TranslateMemoryScope(coherentFlags))));
}
} else if (arg == 2) {
continue;
}
}
if (lvalue)
operands.push_back(builder.accessChainGetLValue());
else {
@ -2462,7 +2541,33 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
}
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
if (atomic) {
if (node->getOp() == glslang::EOpCooperativeMatrixLoad) {
std::vector<spv::IdImmediate> idImmOps;
idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf
idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride
idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor
idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end());
// get the pointee type
spv::Id typeId = builder.getContainedTypeId(builder.getTypeId(operands[0]));
assert(builder.isCooperativeMatrixType(typeId));
// do the op
spv::Id result = builder.createOp(spv::OpCooperativeMatrixLoadNV, typeId, idImmOps);
// store the result to the pointer (out param 'm')
builder.createStore(result, operands[0]);
result = 0;
} else if (node->getOp() == glslang::EOpCooperativeMatrixStore) {
std::vector<spv::IdImmediate> idImmOps;
idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf
idImmOps.push_back(spv::IdImmediate(true, operands[0])); // object
idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride
idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor
idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end());
builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps);
result = 0;
} else if (atomic) {
// Handle all atomics
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType());
} else {
@ -3090,6 +3195,19 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
spvType = builder.makeVectorType(spvType, type.getVectorSize());
}
if (type.isCoopMat()) {
builder.addCapability(spv::CapabilityCooperativeMatrixNV);
builder.addExtension(spv::E_SPV_NV_cooperative_matrix);
if (type.getBasicType() == glslang::EbtFloat16)
builder.addCapability(spv::CapabilityFloat16);
spv::Id scope = makeArraySizeId(*type.getTypeParameters(), 1);
spv::Id rows = makeArraySizeId(*type.getTypeParameters(), 2);
spv::Id cols = makeArraySizeId(*type.getTypeParameters(), 3);
spvType = builder.makeCooperativeMatrixType(spvType, scope, rows, cols);
}
if (type.isArray()) {
int stride = 0; // keep this 0 unless doing an explicit layout; 0 will mean no decoration, no stride
@ -4847,7 +4965,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
// handle mapped binary operations (should be non-comparison)
if (binOp != spv::OpNop) {
assert(comparison == false);
if (builder.isMatrix(left) || builder.isMatrix(right))
if (builder.isMatrix(left) || builder.isMatrix(right) ||
builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right))
return createBinaryMatrixOperation(binOp, decorations, typeId, left, right);
// No matrix involved; make both operands be the same number of components, if needed
@ -4968,7 +5087,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
firstClass = false;
break;
case spv::OpMatrixTimesScalar:
if (builder.isMatrix(right))
if (builder.isMatrix(right) || builder.isCooperativeMatrix(right))
std::swap(left, right);
assert(builder.isScalar(right));
break;
@ -4989,6 +5108,9 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
break;
}
if (builder.isCooperativeMatrix(left) || builder.isCooperativeMatrix(right))
firstClass = true;
if (firstClass) {
spv::Id result = builder.createBinOp(op, typeId, left, right);
builder.addDecoration(result, decorations.noContraction);
@ -7030,6 +7152,10 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands);
return 0;
#endif
case glslang::EOpCooperativeMatrixMulAdd:
opCode = spv::OpCooperativeMatrixMulAddNV;
break;
default:
return 0;
}
@ -7486,6 +7612,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla
glslang::TType vectorType(glslangType, 0);
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
spvConsts.push_back(createSpvConstantFromConstUnionArray(vectorType, consts, nextConst, false));
} else if (glslangType.isCoopMat()) {
glslang::TType componentType(glslangType.getBasicType());
spvConsts.push_back(createSpvConstantFromConstUnionArray(componentType, consts, nextConst, false));
} else if (glslangType.isStruct()) {
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)

60
SPIRV/SpvBuilder.cpp Executable file → Normal file
View File

@ -388,6 +388,33 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
return type->getResultId();
}
Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols)
{
// try to find it
Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) {
type = groupedTypes[OpTypeCooperativeMatrixNV][t];
if (type->getIdOperand(0) == component &&
type->getIdOperand(1) == scope &&
type->getIdOperand(2) == rows &&
type->getIdOperand(3) == cols)
return type->getResultId();
}
// not found, make it
type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixNV);
type->addIdOperand(component);
type->addIdOperand(scope);
type->addIdOperand(rows);
type->addIdOperand(cols);
groupedTypes[OpTypeCooperativeMatrixNV].push_back(type);
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
return type->getResultId();
}
// TODO: performance: track arrays per stride
// If a stride is supplied (non-zero) make an array.
// If no stride (0), reuse previous array types.
@ -623,6 +650,9 @@ int Builder::getNumTypeConstituents(Id typeId) const
}
case OpTypeStruct:
return instr->getNumOperands();
case OpTypeCooperativeMatrixNV:
// has only one constituent when used with OpCompositeConstruct.
return 1;
default:
assert(0);
return 1;
@ -669,6 +699,7 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
case OpTypeMatrix:
case OpTypeArray:
case OpTypeRuntimeArray:
case OpTypeCooperativeMatrixNV:
return instr->getIdOperand(0);
case OpTypePointer:
return instr->getIdOperand(1);
@ -981,15 +1012,14 @@ Id Builder::makeFpConstant(Id type, double d, bool specConstant)
return NoResult;
}
Id Builder::findCompositeConstant(Op typeClass, const std::vector<Id>& comps)
Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps)
{
Instruction* constant = 0;
bool found = false;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
constant = groupedConstants[typeClass][i];
// same shape?
if (constant->getNumOperands() != (int)comps.size())
if (constant->getTypeId() != typeId)
continue;
// same contents?
@ -1044,8 +1074,9 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector<Id>& members, boo
case OpTypeVector:
case OpTypeArray:
case OpTypeMatrix:
case OpTypeCooperativeMatrixNV:
if (! specConstant) {
Id existing = findCompositeConstant(typeClass, members);
Id existing = findCompositeConstant(typeClass, typeId, members);
if (existing)
return existing;
}
@ -1408,6 +1439,23 @@ Id Builder::createArrayLength(Id base, unsigned int member)
return length->getResultId();
}
Id Builder::createCooperativeMatrixLength(Id type)
{
spv::Id intType = makeUintType(32);
// Generate code for spec constants if in spec constant operation
// generation mode.
if (generatingOpCodeForSpecConst) {
return createSpecConstantOp(OpCooperativeMatrixLengthNV, intType, std::vector<Id>(1, type), std::vector<Id>());
}
Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthNV);
length->addIdOperand(type);
buildPoint->addInstruction(std::unique_ptr<Instruction>(length));
return length->getResultId();
}
Id Builder::createCompositeExtract(Id composite, Id typeId, unsigned index)
{
// Generate code for spec constants if in spec constant operation
@ -2598,9 +2646,9 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
}
}
if (constant)
if (constant) {
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
else {
} else {
// make a new function variable for this r-value
Id lValue = createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");

10
SPIRV/SpvBuilder.h Executable file → Normal file
View File

@ -155,6 +155,7 @@ public:
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
Id makeSamplerType();
Id makeSampledImageType(Id imageType);
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
// accelerationStructureNV type
Id makeAccelerationStructureNVType();
@ -178,6 +179,7 @@ public:
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); }
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
@ -191,7 +193,8 @@ public:
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); }
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
@ -314,6 +317,9 @@ public:
// Create an OpArrayLength instruction
Id createArrayLength(Id base, unsigned int member);
// Create an OpCooperativeMatrixLengthNV instruction
Id createCooperativeMatrixLength(Id type);
// Create an OpCompositeExtract instruction
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
@ -670,7 +676,7 @@ public:
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
Id findCompositeConstant(Op typeClass, const std::vector<Id>& comps);
Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
Id collapseAccessChain();
void remapDynamicSwizzle();

View File

@ -930,6 +930,10 @@ const char* CapabilityString(int info)
case CapabilityPhysicalStorageBufferAddressesEXT: return "CapabilityPhysicalStorageBufferAddressesEXT";
case CapabilityVariablePointers: return "CapabilityVariablePointers";
case CapabilityCooperativeMatrixNV: return "CapabilityCooperativeMatrixNV";
default: return "Bad";
}
}
@ -1333,6 +1337,12 @@ const char* OpcodeString(int op)
case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV";
#endif
case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV";
case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV";
case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV";
case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV";
case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV";
default:
return "Bad";
}
@ -1444,6 +1454,8 @@ void Parameterize()
InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false);
InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false);
InstructionDesc[OpModuleProcessed].setResultAndType(false, false);
InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false);
InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false);
// Specific additional context-dependent operands
@ -2714,6 +2726,32 @@ void Parameterize()
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'");
InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'");
#endif
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'");
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'");
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Rows'");
InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Columns'");
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Stride'");
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Column Major'");
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandMemoryAccess, "'Memory Access'");
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandLiteralNumber, "", true);
InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "", true);
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Object'");
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Stride'");
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Column Major'");
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandMemoryAccess, "'Memory Access'");
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandLiteralNumber, "", true);
InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "", true);
InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'A'");
InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'B'");
InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'");
InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'");
}
}; // end spv namespace

View File

@ -811,6 +811,7 @@ enum Capability {
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
CapabilityPhysicalStorageBufferAddressesEXT = 5347,
CapabilityComputeDerivativeGroupLinearNV = 5350,
CapabilityCooperativeMatrixNV = 5357,
CapabilitySubgroupShuffleINTEL = 5568,
CapabilitySubgroupBufferBlockIOINTEL = 5569,
CapabilitySubgroupImageBlockIOINTEL = 5570,
@ -1183,6 +1184,11 @@ enum Op {
OpTraceNV = 5337,
OpTypeAccelerationStructureNV = 5341,
OpExecuteCallableNV = 5344,
OpTypeCooperativeMatrixNV = 5358,
OpCooperativeMatrixLoadNV = 5359,
OpCooperativeMatrixStoreNV = 5360,
OpCooperativeMatrixMulAddNV = 5361,
OpCooperativeMatrixLengthNV = 5362,
OpSubgroupShuffleINTEL = 5571,
OpSubgroupShuffleDownINTEL = 5572,
OpSubgroupShuffleUpINTEL = 5573,

View File

@ -83,6 +83,7 @@ const MemorySemanticsMask MemorySemanticsAllMemory =
struct IdImmediate {
bool isId; // true if word is an Id, false if word is an immediate
unsigned word;
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
};
//

View File

@ -0,0 +1,95 @@
spv.1.3.coopmat.comp
// Module Version 10300
// Generated by (magic number): 80007
// Id's are bound by 52
Capability Shader
Capability CapabilityVariablePointers
Capability CapabilityVulkanMemoryModelKHR
Capability CapabilityCooperativeMatrixNV
Extension "SPV_KHR_vulkan_memory_model"
Extension "SPV_NV_cooperative_matrix"
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical VulkanKHR
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 64 1 1
Source GLSL 450
SourceExtension "GL_EXT_shader_explicit_arithmetic_types_float16"
SourceExtension "GL_KHR_memory_scope_semantics"
SourceExtension "GL_NV_cooperative_matrix"
Name 4 "main"
Name 13 "m"
Name 29 "tempArg"
Name 33 "Block"
MemberName 33(Block) 0 "y"
MemberName 33(Block) 1 "x"
Name 35 "block"
Decorate 31 ArrayStride 4
Decorate 32 ArrayStride 4
MemberDecorate 33(Block) 0 Offset 0
MemberDecorate 33(Block) 1 Offset 4194304
Decorate 33(Block) Block
Decorate 35(block) DescriptorSet 0
Decorate 35(block) Binding 0
Decorate 51 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 8
11: TypeCooperativeMatrixNV 6(float) 8 9 10
12: TypePointer Function 11
14: 6(float) Constant 0
15: 11 ConstantComposite 14
24: 6(float) Constant 1073741824
30: 7(int) Constant 1048576
31: TypeArray 6(float) 30
32: TypeRuntimeArray 6(float)
33(Block): TypeStruct 31 32
34: TypePointer StorageBuffer 33(Block)
35(block): 34(ptr) Variable StorageBuffer
36: TypeInt 32 1
37: 36(int) Constant 1
38: 7(int) Constant 5
39: TypePointer StorageBuffer 6(float)
41: 7(int) Constant 128
42: TypeBool
43: 42(bool) ConstantFalse
48: TypeVector 7(int) 3
49: 7(int) Constant 64
50: 7(int) Constant 1
51: 48(ivec3) ConstantComposite 49 50 50
4(main): 2 Function None 3
5: Label
13(m): 12(ptr) Variable Function
29(tempArg): 12(ptr) Variable Function
Store 13(m) 15
16: 11 Load 13(m)
17: 11 Load 13(m)
18: 11 FAdd 16 17
Store 13(m) 18
19: 11 Load 13(m)
20: 11 Load 13(m)
21: 11 FSub 19 20
Store 13(m) 21
22: 11 Load 13(m)
23: 11 FNegate 22
Store 13(m) 23
25: 11 Load 13(m)
26: 11 MatrixTimesScalar 25 24
Store 13(m) 26
27: 11 Load 13(m)
28: 11 MatrixTimesScalar 27 24
Store 13(m) 28
40: 39(ptr) AccessChain 35(block) 37 9
44: 11 CooperativeMatrixLoadNV 40 41 43 MakePointerVisibleKHR NonPrivatePointerKHR 38
Store 29(tempArg) 44
45: 11 Load 29(tempArg)
Store 13(m) 45
46: 11 Load 13(m)
47: 39(ptr) AccessChain 35(block) 37 9
CooperativeMatrixStoreNV 47 46 41 43 MakePointerAvailableKHR NonPrivatePointerKHR 38
Return
FunctionEnd

View File

@ -0,0 +1,375 @@
spv.coopmat.comp
// Module Version 10000
// Generated by (magic number): 80007
// Id's are bound by 228
Capability Shader
Capability Float16
Capability StorageUniformBufferBlock16
Capability CapabilityVulkanMemoryModelKHR
Capability CapabilityPhysicalStorageBufferAddressesEXT
Capability CapabilityCooperativeMatrixNV
Extension "SPV_EXT_physical_storage_buffer"
Extension "SPV_KHR_16bit_storage"
Extension "SPV_KHR_storage_buffer_storage_class"
Extension "SPV_KHR_vulkan_memory_model"
Extension "SPV_NV_cooperative_matrix"
1: ExtInstImport "GLSL.std.450"
MemoryModel PhysicalStorageBuffer64EXT VulkanKHR
EntryPoint GLCompute 4 "main"
ExecutionMode 4 LocalSize 64 1 1
Source GLSL 450
SourceExtension "GL_EXT_buffer_reference"
SourceExtension "GL_EXT_shader_explicit_arithmetic_types_float16"
SourceExtension "GL_KHR_memory_scope_semantics"
SourceExtension "GL_NV_cooperative_matrix"
Name 4 "main"
Name 14 "f16(f161;"
Name 13 "m"
Name 21 "f32(f1;"
Name 20 "m"
Name 34 "m"
Name 52 "m2"
Name 56 "x"
Name 64 "tempArg"
Name 68 "Block"
MemberName 68(Block) 0 "y"
MemberName 68(Block) 1 "x"
Name 70 "block"
Name 81 "tempArg"
Name 86 "Block16"
MemberName 86(Block16) 0 "y"
MemberName 86(Block16) 1 "x"
MemberName 86(Block16) 2 "b"
Name 89 "Block"
MemberName 89(Block) 0 "y"
MemberName 89(Block) 1 "x"
Name 91 "block16"
Name 98 "tempArg"
Name 111 "D"
Name 112 "A"
Name 114 "B"
Name 116 "C"
Name 120 "l"
Name 124 "Y"
Name 125 "Z"
Name 128 "F"
Name 133 "a"
Name 137 "md1"
Name 148 "mC2"
Name 153 "tempArg"
Name 159 "tempArg"
Name 165 "p1"
Name 166 "param"
Name 169 "p2"
Name 170 "param"
Name 184 "tempArg"
Name 189 "shmatrix"
Name 194 "ms"
Name 201 "mC"
Name 206 "arr"
Name 211 "arr2"
Name 212 "F"
Name 217 "S"
MemberName 217(S) 0 "a"
MemberName 217(S) 1 "b"
MemberName 217(S) 2 "c"
Name 222 "SC"
Name 227 "scm"
Decorate 66 ArrayStride 4
Decorate 67 ArrayStride 4
MemberDecorate 68(Block) 0 Offset 0
MemberDecorate 68(Block) 1 Offset 4194304
Decorate 68(Block) Block
Decorate 70(block) DescriptorSet 0
Decorate 70(block) Binding 0
Decorate 82 ArrayStride 2
Decorate 84 ArrayStride 2
MemberDecorate 86(Block16) 0 Offset 0
MemberDecorate 86(Block16) 1 Offset 2097152
MemberDecorate 86(Block16) 2 Offset 2097160
Decorate 86(Block16) Block
Decorate 87 ArrayStride 4
Decorate 88 ArrayStride 4
MemberDecorate 89(Block) 0 Offset 0
MemberDecorate 89(Block) 1 Offset 4194304
Decorate 89(Block) Block
Decorate 91(block16) DescriptorSet 0
Decorate 91(block16) Binding 0
Decorate 124(Y) SpecId 0
Decorate 200 BuiltIn WorkgroupSize
Decorate 212(F) SpecId 1
Decorate 222(SC) SpecId 2
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 16
7: TypeInt 32 0
8: 7(int) Constant 3
9: 7(int) Constant 8
10: TypeCooperativeMatrixNV 6(float16_t) 8 9 9
11: TypePointer Function 10
12: TypeFunction 10 11(ptr)
16: TypeFloat 32
17: TypeCooperativeMatrixNV 16(float) 8 9 9
18: TypePointer Function 17
19: TypeFunction 17 18(ptr)
31: 7(int) Constant 16
32: TypeCooperativeMatrixNV 16(float) 8 31 9
33: TypePointer Function 32
35: 16(float) Constant 0
36: 32 ConstantComposite 35
45: 16(float) Constant 1073741824
50: TypeCooperativeMatrixNV 6(float16_t) 8 31 9
51: TypePointer Function 50
55: TypePointer Function 16(float)
57: TypeInt 32 1
58: 57(int) Constant 1
61: 57(int) Constant 0
65: 7(int) Constant 1048576
66: TypeArray 16(float) 65
67: TypeRuntimeArray 16(float)
68(Block): TypeStruct 66 67
69: TypePointer StorageBuffer 68(Block)
70(block): 69(ptr) Variable StorageBuffer
71: 7(int) Constant 5
72: TypePointer StorageBuffer 16(float)
74: 7(int) Constant 128
75: TypeBool
76: 75(bool) ConstantFalse
82: TypeArray 6(float16_t) 65
83: 7(int) Constant 1
84: TypeArray 6(float16_t) 83
TypeForwardPointer 85 PhysicalStorageBufferEXT
86(Block16): TypeStruct 82 84 85
87: TypeArray 16(float) 65
88: TypeRuntimeArray 16(float)
89(Block): TypeStruct 87 88
85: TypePointer PhysicalStorageBufferEXT 89(Block)
90: TypePointer StorageBuffer 86(Block16)
91(block16): 90(ptr) Variable StorageBuffer
92: TypePointer StorageBuffer 6(float16_t)
99: 57(int) Constant 2
100: TypePointer StorageBuffer 85(ptr)
103: TypePointer PhysicalStorageBufferEXT 16(float)
119: TypePointer Function 57(int)
121: 7(int) SpecConstantOp 5362 32
122: 57(int) SpecConstantOp 128 121 61
123: 57(int) Constant 8
124(Y): 57(int) SpecConstant 2
125(Z): 57(int) SpecConstantOp 132 123 124(Y)
126: TypeCooperativeMatrixNV 6(float16_t) 8 125(Z) 125(Z)
127: TypePointer Function 126
129:6(float16_t) Constant 0
130: 126 ConstantComposite 129
131: TypeArray 32 71
132: TypePointer Function 131
134: 57(int) Constant 3
135: 16(float) Constant 1065353216
141: 57(int) Constant 1234
145: TypeCooperativeMatrixNV 6(float16_t) 8 125(Z) 9
146: TypeArray 145 8
147: TypePointer Private 146
148(mC2): 147(ptr) Variable Private
149: TypePointer Private 145
173: 10 ConstantComposite 129
174: 17 ConstantComposite 35
178:6(float16_t) Constant 16384
181: 16(float) Constant 1082130432
185: TypeVector 7(int) 4
186: 7(int) Constant 32
187: TypeArray 185(ivec4) 186
188: TypePointer Workgroup 187
189(shmatrix): 188(ptr) Variable Workgroup
190: 7(int) Constant 2
191: TypePointer Workgroup 185(ivec4)
198: TypeVector 7(int) 3
199: 7(int) Constant 64
200: 198(ivec3) ConstantComposite 199 83 83
201(mC): 149(ptr) Variable Private
202: 7(int) SpecConstantOp 5362 145
203: 57(int) SpecConstantOp 128 202 61
204: TypeArray 57(int) 203
205: TypePointer Private 204
206(arr): 205(ptr) Variable Private
207: 7(int) SpecConstantOp 5362 145
208: 57(int) SpecConstantOp 128 207 61
209: TypeArray 57(int) 208
210: TypePointer Private 209
211(arr2): 210(ptr) Variable Private
212(F): 16(float) SpecConstant 1077936128
213: TypeCooperativeMatrixNV 16(float) 8 125(Z) 9
214: 213 ConstantComposite 35
215:6(float16_t) Constant 15360
216: 10 ConstantComposite 215
217(S): TypeStruct 57(int) 57(int) 57(int)
218: 57(int) Constant 12
219: 57(int) Constant 23
220: 57(int) Constant 34
221: 217(S) ConstantComposite 218 219 220
222(SC): 57(int) SpecConstant 1
223: TypeCooperativeMatrixNV 6(float16_t) 8 222(SC) 222(SC)
224: TypeArray 223 222(SC)
225: TypeArray 224 222(SC)
226: TypePointer Private 225
227(scm): 226(ptr) Variable Private
4(main): 2 Function None 3
5: Label
34(m): 33(ptr) Variable Function
52(m2): 51(ptr) Variable Function
56(x): 55(ptr) Variable Function
64(tempArg): 33(ptr) Variable Function
81(tempArg): 51(ptr) Variable Function
98(tempArg): 33(ptr) Variable Function
111(D): 33(ptr) Variable Function
112(A): 51(ptr) Variable Function
114(B): 11(ptr) Variable Function
116(C): 33(ptr) Variable Function
120(l): 119(ptr) Variable Function
128(F): 127(ptr) Variable Function
133(a): 132(ptr) Variable Function
137(md1): 55(ptr) Variable Function
153(tempArg): 33(ptr) Variable Function
159(tempArg): 51(ptr) Variable Function
165(p1): 11(ptr) Variable Function
166(param): 11(ptr) Variable Function
169(p2): 18(ptr) Variable Function
170(param): 18(ptr) Variable Function
184(tempArg): 51(ptr) Variable Function
194(ms): 51(ptr) Variable Function
Store 34(m) 36
37: 32 Load 34(m)
38: 32 Load 34(m)
39: 32 FAdd 37 38
Store 34(m) 39
40: 32 Load 34(m)
41: 32 Load 34(m)
42: 32 FSub 40 41
Store 34(m) 42
43: 32 Load 34(m)
44: 32 FNegate 43
Store 34(m) 44
46: 32 Load 34(m)
47: 32 MatrixTimesScalar 46 45
Store 34(m) 47
48: 32 Load 34(m)
49: 32 MatrixTimesScalar 48 45
Store 34(m) 49
53: 32 Load 34(m)
54: 50 FConvert 53
Store 52(m2) 54
59: 55(ptr) AccessChain 34(m) 58
60: 16(float) Load 59
Store 56(x) 60
62: 16(float) Load 56(x)
63: 55(ptr) AccessChain 34(m) 61
Store 63 62
73: 72(ptr) AccessChain 70(block) 58 31
77: 32 CooperativeMatrixLoadNV 73 74 76 MakePointerVisibleKHR NonPrivatePointerKHR 71
Store 64(tempArg) 77
78: 32 Load 64(tempArg)
Store 34(m) 78
79: 32 Load 34(m)
80: 72(ptr) AccessChain 70(block) 58 31
CooperativeMatrixStoreNV 80 79 74 76 MakePointerAvailableKHR NonPrivatePointerKHR 71
93: 92(ptr) AccessChain 91(block16) 58 31
94: 50 CooperativeMatrixLoadNV 93 74 76 MakePointerVisibleKHR NonPrivatePointerKHR 71
Store 81(tempArg) 94
95: 50 Load 81(tempArg)
Store 52(m2) 95
96: 50 Load 52(m2)
97: 92(ptr) AccessChain 91(block16) 58 31
CooperativeMatrixStoreNV 97 96 74 76 MakePointerAvailableKHR NonPrivatePointerKHR 71
101: 100(ptr) AccessChain 91(block16) 99
102: 85(ptr) Load 101 MakePointerVisibleKHR NonPrivatePointerKHR 71
104: 103(ptr) AccessChain 102 58 31
105: 32 CooperativeMatrixLoadNV 104 74 76 Aligned 16
Store 98(tempArg) 105
106: 32 Load 98(tempArg)
Store 34(m) 106
107: 32 Load 34(m)
108: 100(ptr) AccessChain 91(block16) 99
109: 85(ptr) Load 108 MakePointerVisibleKHR NonPrivatePointerKHR 71
110: 103(ptr) AccessChain 109 58 31
CooperativeMatrixStoreNV 110 107 74 76 Aligned 16
113: 50 Load 112(A)
115: 10 Load 114(B)
117: 32 Load 116(C)
118: 32 CooperativeMatrixMulAddNV 113 115 117
Store 111(D) 118
Store 120(l) 122
Store 128(F) 130
136: 55(ptr) AccessChain 133(a) 134 61
Store 136 135
Store 137(md1) 35
138: 32 Load 34(m)
139: 32 Load 34(m)
140: 32 FAdd 139 138
Store 34(m) 140
142: 16(float) CompositeExtract 140 1234
143: 16(float) Load 137(md1)
144: 16(float) FAdd 143 142
Store 137(md1) 144
150: 149(ptr) AccessChain 148(mC2) 99
151: 145 Load 150
152: 149(ptr) AccessChain 148(mC2) 58
Store 152 151
154: 72(ptr) AccessChain 70(block) 61 31
155: 32 CooperativeMatrixLoadNV 154 74 76 MakePointerVisibleKHR NonPrivatePointerKHR 71
Store 153(tempArg) 155
156: 32 Load 153(tempArg)
Store 34(m) 156
157: 32 Load 34(m)
158: 72(ptr) AccessChain 70(block) 61 31
CooperativeMatrixStoreNV 158 157 74 76 MakePointerAvailableKHR NonPrivatePointerKHR 71
160: 92(ptr) AccessChain 91(block16) 61 31
161: 50 CooperativeMatrixLoadNV 160 74 76 MakePointerVisibleKHR NonPrivatePointerKHR 71
Store 159(tempArg) 161
162: 50 Load 159(tempArg)
Store 52(m2) 162
163: 50 Load 52(m2)
164: 92(ptr) AccessChain 91(block16) 61 31
CooperativeMatrixStoreNV 164 163 74 76 MakePointerAvailableKHR NonPrivatePointerKHR 71
167: 10 Load 165(p1)
Store 166(param) 167
168: 10 FunctionCall 14(f16(f161;) 166(param)
Store 165(p1) 168
171: 17 Load 169(p2)
Store 170(param) 171
172: 17 FunctionCall 21(f32(f1;) 170(param)
Store 169(p2) 172
Store 165(p1) 173
Store 169(p2) 174
175: 10 Load 165(p1)
176: 10 Load 165(p1)
177: 10 FDiv 176 175
Store 165(p1) 177
179: 10 Load 165(p1)
180: 10 MatrixTimesScalar 179 178
Store 165(p1) 180
182: 17 Load 169(p2)
183: 17 MatrixTimesScalar 182 181
Store 169(p2) 183
192: 191(ptr) AccessChain 189(shmatrix) 83
193: 50 CooperativeMatrixLoadNV 192 190 76 MakePointerVisibleKHR NonPrivatePointerKHR 190
Store 184(tempArg) 193
195: 50 Load 184(tempArg)
Store 194(ms) 195
196: 50 Load 194(ms)
197: 191(ptr) AccessChain 189(shmatrix) 83
CooperativeMatrixStoreNV 197 196 190 76 MakePointerAvailableKHR NonPrivatePointerKHR 190
Return
FunctionEnd
14(f16(f161;): 10 Function None 12
13(m): 11(ptr) FunctionParameter
15: Label
23: 10 Load 13(m)
24: 10 FNegate 23
ReturnValue 24
FunctionEnd
21(f32(f1;): 17 Function None 19
20(m): 18(ptr) FunctionParameter
22: Label
27: 17 Load 20(m)
28: 17 FNegate 27
ReturnValue 28
FunctionEnd

View File

@ -0,0 +1,35 @@
spv.coopmat_Error.comp
ERROR: 0:8: 'ftemplate16' : unexpected type parameters
ERROR: 0:10: 'fnoparams' : expected four type parameters
ERROR: 0:12: 'fbadbits' : expected 16, 32, or 64 bits for first type parameter
ERROR: 0:14: 'fbadnumparams' : expected four type parameters
ERROR: 0:18: '' : type parameter must be a constant integer expression
ERROR: 0:20: 'constant_id' : can only be applied to 'const'-qualified scalar
ERROR: 0:22: 'Cooperative matrix types must not be used in shared memory' : qualifier
ERROR: 0:25: 'bufmat' : member of block cannot be or contain a cooperative matrix type
ERROR: 0:34: 'assign' : cannot convert from ' temp<16, 3, 16, 8> float16_t' to ' temp<32, 3, 16, 8> highp float'
ERROR: 0:35: 'assign' : cannot convert from ' temp<16, 3, 16, 8> float16_t' to ' temp<32, 3, 16, 8> highp float'
ERROR: 0:40: 'assign' : cannot convert from ' temp<16, 3, 8, 8> float16_t' to ' temp<16, 3, 16, 8> float16_t'
ERROR: 0:46: 'assign' : cannot convert from ' temp<16, 3, 8, 1> float16_t' to ' temp<16, 3, 8, 1> float16_t'
ERROR: 0:49: 'constructor' : too many arguments
ERROR: 0:49: 'assign' : cannot convert from ' const float' to ' temp<16, 3, 8, 8> float16_t'
ERROR: 0:53: 'constructor' : Cooperative matrix constructor argument must be scalar or cooperative matrix
ERROR: 0:53: '=' : cannot convert from ' const float' to ' temp<32, 3, 4, 4> highp float'
ERROR: 0:56: 'expression' : left of '[' is not of type array, matrix, or vector
ERROR: 0:59: '.' : cannot apply to a cooperative matrix type: x
ERROR: 0:61: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' temp<16, 3, 16, 8> float16_t' and a right operand of type ' temp<16, 3, 16, 8> float16_t' (or there is no acceptable conversion)
ERROR: 0:63: '+' : wrong operand types: no operation '+' exists that takes a left-hand operand of type ' temp<16, 3, 16, 8> float16_t' and a right operand of type ' const float' (or there is no acceptable conversion)
ERROR: 0:64: '-' : wrong operand types: no operation '-' exists that takes a left-hand operand of type ' temp<16, 3, 16, 8> float16_t' and a right operand of type ' const float' (or there is no acceptable conversion)
ERROR: 0:65: '/' : wrong operand types: no operation '/' exists that takes a left-hand operand of type ' temp<16, 3, 16, 8> float16_t' and a right operand of type ' const float' (or there is no acceptable conversion)
ERROR: 0:66: 'assign' : cannot convert from ' const float' to ' temp<16, 3, 16, 8> float16_t'
ERROR: 0:67: 'assign' : cannot convert from ' const float' to ' temp<16, 3, 16, 8> float16_t'
ERROR: 0:68: 'assign' : cannot convert from ' const float' to ' temp<16, 3, 16, 8> float16_t'
ERROR: 0:70: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' temp<16, 3, 16, 8> float16_t' and a right operand of type ' const float' (or there is no acceptable conversion)
ERROR: 0:71: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' const float' and a right operand of type ' temp<16, 3, 16, 8> float16_t' (or there is no acceptable conversion)
ERROR: 0:72: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' temp<32, 3, 16, 8> highp float' and a right operand of type ' const float16_t' (or there is no acceptable conversion)
ERROR: 0:73: '*' : wrong operand types: no operation '*' exists that takes a left-hand operand of type ' const float16_t' and a right operand of type ' temp<32, 3, 16, 8> highp float' (or there is no acceptable conversion)
ERROR: 0:75: 'transpose' : no matching overloaded function found
ERROR: 30 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

View File

@ -30,14 +30,11 @@ ERROR: 0:32: 'initializer' : can't use with types containing arrays sized with a
ERROR: 0:34: '=' : can't use with types containing arrays sized with a specialization constant
ERROR: 0:35: '==' : can't use with types containing arrays sized with a specialization constant
ERROR: 0:39: 'set' : cannot be used with push_constant
ERROR: 0:49: '[]' : only outermost dimension of an array of arrays can be a specialization constant
ERROR: 0:50: '[]' : only outermost dimension of an array of arrays can be a specialization constant
ERROR: 0:51: '[]' : only outermost dimension of an array of arrays can be a specialization constant
ERROR: 0:54: '[]' : only outermost dimension of an array of arrays can be a specialization constant
ERROR: 0:54: 'location' : SPIR-V requires location for user input/output
ERROR: 0:58: 'location' : SPIR-V requires location for user input/output
ERROR: 0:65: 'location' : overlapping use of location 10
ERROR: 38 compilation errors. No code generated.
ERROR: 35 compilation errors. No code generated.
SPIR-V is not generated for failed compile or link

28
Test/spv.1.3.coopmat.comp Normal file
View File

@ -0,0 +1,28 @@
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_NV_cooperative_matrix : enable
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
#pragma use_variable_pointers
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
layout(set = 0, binding = 0) coherent buffer Block {
float y[1024*1024];
float x[];
} block;
void main()
{
fcoopmatNV<32, gl_ScopeSubgroup, 16, 8> m = fcoopmatNV<32, gl_ScopeSubgroup, 16, 8>(0.0);
m = m + m;
m = m - m;
m = -m;
m = 2.0*m;
m = m*2.0;
coopMatLoadNV(m, block.x, 16, 128, false);
coopMatStoreNV(m, block.x, 16, 128, false);
}

115
Test/spv.coopmat.comp Normal file
View File

@ -0,0 +1,115 @@
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_NV_cooperative_matrix : enable
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
#extension GL_EXT_buffer_reference : enable
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
const int X = 8;
layout(constant_id = 0) const int Y = 2;
const int Z = X*Y;
fcoopmatNV<16, gl_ScopeSubgroup, Z, 8> mC;
fcoopmatNV<16, gl_ScopeSubgroup, Z, 8> mC2[3];
int arr[mC.length()];
int arr2[mC2[1].length()];
layout(constant_id = 1) const float F = 3.0;
const fcoopmatNV<32, gl_ScopeSubgroup, Z, 8> mD = fcoopmatNV<32, gl_ScopeSubgroup, Z, 8>(0.0);
const fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> mD2 = fcoopmatNV<16, gl_ScopeSubgroup, 8, 8>(1);
struct S { int a; int b; int c; };
const S s = S(12, 23, 34);
layout(set = 0, binding = 0, buffer_reference) coherent buffer Block {
float y[1024*1024];
float x[];
} block;
layout(set = 0, binding = 0) coherent buffer Block16 {
float16_t y[1024*1024];
float16_t x[];
Block b;
} block16;
fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> f16(fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> m) { return -m; }
fcoopmatNV<32, gl_ScopeSubgroup, 8, 8> f32(fcoopmatNV<32, gl_ScopeSubgroup, 8, 8> m) { return -m; }
layout(constant_id = 2) const int SC = 1;
fcoopmatNV<16, gl_ScopeSubgroup, SC, SC> scm[SC][SC];
// sized for fcoopmatNV<16, gl_ScopeSubgroup, 16, 16>
shared uvec4 shmatrix[16*16*2/16];
void main()
{
fcoopmatNV<32, gl_ScopeSubgroup, 16, (2>1?8:4)> m = fcoopmatNV<32, gl_ScopeSubgroup, 16, (2>1?8:4)>(0.0);
m = m + m;
m = m - m;
m = -m;
m = 2.0*m;
m = m*2.0;
fcoopmatNV<16, gl_ScopeSubgroup, 16, 8> m2 = fcoopmatNV<16, gl_ScopeSubgroup, 16, 8>(m);
float x = m[1];
m[0] = x;
coopMatLoadNV(m, block.x, 16, 128, false);
coopMatStoreNV(m, block.x, 16, 128, false);
coopMatLoadNV(m2, block16.x, 16, 128, false);
coopMatStoreNV(m2, block16.x, 16, 128, false);
coopMatLoadNV(m, block16.b.x, 16, 128, false);
coopMatStoreNV(m, block16.b.x, 16, 128, false);
fcoopmatNV<16, gl_ScopeSubgroup, 16, 8> A;
fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> B;
fcoopmatNV<32, gl_ScopeSubgroup, 16, 8> C;
fcoopmatNV<32, gl_ScopeSubgroup, 16, 8> D;
D = coopMatMulAddNV(A, B, C);
int l = D.length();
fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> E;
fcoopmatNV<16, gl_ScopeSubgroup, Z, Z> F = fcoopmatNV<16, gl_ScopeSubgroup, Z, Z>(0.0);
fcoopmatNV<32, gl_ScopeSubgroup, 16, (2>1?8:4)> a[5];
a[3][0] = 1.0;
float md1 = mD[1];
md1 += (m += m)[1234];
mC2[1] = mC2[2];
coopMatLoadNV(m, block.y, 16, 128, false);
coopMatStoreNV(m, block.y, 16, 128, false);
coopMatLoadNV(m2, block16.y, 16, 128, false);
coopMatStoreNV(m2, block16.y, 16, 128, false);
fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> p1;
fcoopmatNV<32, gl_ScopeSubgroup, 8, 8> p2;
p1 = f16(p1);
p2 = f32(p2);
p1 = fcoopmatNV<16, gl_ScopeSubgroup, 8, 8>(0.0);
p2 = fcoopmatNV<32, gl_ScopeSubgroup, 8, 8>(0.0);
p1 /= p1;
p1 *= float16_t(2.0);
p2 *= 4.0;
fcoopmatNV<16, gl_ScopeSubgroup, 16, 8> ms;
coopMatLoadNV(ms, shmatrix, 1, 2, false);
coopMatStoreNV(ms, shmatrix, 1, 2, false);
}

View File

@ -0,0 +1,76 @@
#version 450 core
#extension GL_KHR_memory_scope_semantics : enable
#extension GL_NV_cooperative_matrix : enable
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : enable
layout (local_size_x = 64, local_size_y = 1, local_size_z = 1) in;
float<16> ftemplate16;
fcoopmatNV fnoparams;
fcoopmatNV<8, gl_ScopeSubgroup, 8, 8> fbadbits;
fcoopmatNV<16, gl_ScopeSubgroup, 8> fbadnumparams;
int X = 8;
fcoopmatNV<16, gl_ScopeSubgroup, 8, X> fbadparam;
layout(constant_id = 0) int Y = 1;
shared fcoopmatNV<16, gl_ScopeSubgroup, 16, 16> sharedmat;
layout(set = 0, binding = 0) buffer InvBlock {
fcoopmatNV<16, gl_ScopeSubgroup, 16, 16> bufmat;
} invblock;
void main()
{
fcoopmatNV<32, gl_ScopeSubgroup, 16, 8> f32_16_8;
fcoopmatNV<16, gl_ScopeSubgroup, 16, 8> f16_16_8;
// invalid implicit conversions
f32_16_8 = f16_16_8;
f32_16_8 = f16_16_8 + f16_16_8;
fcoopmatNV<16, gl_ScopeSubgroup, 8, 8> f16_8_8;
// mismatching dimensions
f16_16_8 = f16_8_8;
fcoopmatNV<16, gl_ScopeSubgroup, 8, Y> f16_8_Y;
fcoopmatNV<16, gl_ScopeSubgroup, 8, (Y+1)> f16_8_Y1;
// mismatching dimensions with specialization constants
f16_8_Y = f16_8_Y1;
// wrong arguments for constructor
f16_8_8 = fcoopmatNV<16, gl_ScopeSubgroup, 8, 8>(1, 1);
// can't construct from a builtin type
mat4 m4;
fcoopmatNV<32, gl_ScopeSubgroup, 4, 4> f32_4_4 = fcoopmatNV<32, gl_ScopeSubgroup, 4, 4>(m4);
// only support a single array subscript
f16_16_8[0][0];
// don't support scalar component selection
f16_16_8.x;
f16_16_8 * f16_16_8;
f16_16_8 + 1.0;
f16_16_8 - 1.0;
f16_16_8 / 1.0;
f16_16_8 += 1.0;
f16_16_8 -= 1.0;
f16_16_8 /= 1.0;
f16_16_8*2.0;
2.0*f16_16_8;
f32_16_8*float16_t(2.0);
float16_t(2.0)*f32_16_8;
transpose(f16_8_8);
}

View File

@ -46,9 +46,9 @@ layout(set = 1, push_constant) uniform badpc { int a; } badpcI; // ERROR, no de
#error VULKAN should be 100
#endif
float AofA0[2][arraySize]; // ERROR, only outer dimension
float AofA1[arraySize][arraySize]; // ERROR, only outer dimension
float AofA2[arraySize][2 + arraySize]; // ERROR, only outer dimension
float AofA0[2][arraySize];
float AofA1[arraySize][arraySize];
float AofA2[arraySize][2 + arraySize];
float AofA3[arraySize][2];
out ban1 { // ERROR, only outer dimension

View File

@ -1235,9 +1235,11 @@ public:
int vectorSize : 4;
int matrixCols : 4;
int matrixRows : 4;
bool coopmat : 1;
TArraySizes* arraySizes;
const TType* userDef;
TSourceLoc loc;
TArraySizes* typeParameters;
void initType(const TSourceLoc& l)
{
@ -1248,6 +1250,8 @@ public:
arraySizes = nullptr;
userDef = nullptr;
loc = l;
typeParameters = nullptr;
coopmat = false;
}
void initQualifiers(bool global = false)
@ -1299,8 +1303,8 @@ public:
// for "empty" type (no args) or simple scalar/vector/matrix
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
{
sampler.clear();
qualifier.clear();
@ -1310,8 +1314,8 @@ public:
// for explicit precision qualifier
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false),
arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
{
sampler.clear();
qualifier.clear();
@ -1323,8 +1327,8 @@ public:
// for turning a TPublicType into a TType, using a shallow copy
explicit TType(const TPublicType& p) :
basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr)
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat),
arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
{
if (basicType == EbtSampler)
sampler = p.sampler;
@ -1340,12 +1344,18 @@ public:
}
typeName = NewPoolTString(p.userDef->getTypeName().c_str());
}
if (p.coopmat && p.basicType == EbtFloat &&
p.typeParameters && p.typeParameters->getNumDims() > 0 &&
p.typeParameters->getDimSize(0) == 16) {
basicType = EbtFloat16;
qualifier.precision = EpqNone;
}
}
// for construction of sampler types
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
sampler(sampler)
sampler(sampler), typeParameters(nullptr)
{
qualifier.clear();
qualifier.storage = q;
@ -1386,13 +1396,16 @@ public:
// dereference from vector to scalar
vectorSize = 1;
vector1 = false;
} else if (isCoopMat()) {
coopmat = false;
typeParameters = nullptr;
}
}
}
// for making structures, ...
TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr)
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
{
sampler.clear();
qualifier.clear();
@ -1400,8 +1413,8 @@ public:
}
// For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr)
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false),
qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
{
sampler.clear();
typeName = NewPoolTString(n.c_str());
@ -1439,6 +1452,8 @@ public:
} else {
referentType = copyOf.referentType;
}
typeParameters = copyOf.typeParameters;
coopmat = copyOf.coopmat;
}
// Make complete copy of the whole type graph rooted at 'copyOf'.
@ -1502,6 +1517,8 @@ public:
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
virtual TArraySizes* getArraySizes() { return arraySizes; }
virtual TType* getReferentType() const { return referentType; }
virtual const TArraySizes* getTypeParameters() const { return typeParameters; }
virtual TArraySizes* getTypeParameters() { return typeParameters; }
virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
@ -1544,6 +1561,8 @@ public:
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
virtual bool isParameterized() const { return typeParameters != nullptr; }
virtual bool isCoopMat() const { return coopmat; }
// return true if this type contains any subtype which satisfies the given predicate.
template <typename P>
@ -1633,6 +1652,11 @@ public:
return containsBasicType(EbtInt8) || containsBasicType(EbtUint8);
}
virtual bool containsCoopMat() const
{
return contains([](const TType* t) { return t->coopmat; } );
}
// Array editing methods. Array descriptors can be shared across
// type instances. This allows all uses of the same array
// to be updated at once. E.g., all nodes can be explicitly sized
@ -1705,6 +1729,46 @@ public:
}
}
void updateTypeParameters(const TType& type)
{
// For when we may already be sharing existing array descriptors,
// keeping the pointers the same, just updating the contents.
assert(typeParameters != nullptr);
assert(type.typeParameters != nullptr);
*typeParameters = *type.typeParameters;
}
void copyTypeParameters(const TArraySizes& s)
{
// For setting a fresh new set of type parameters, not yet worrying about sharing.
typeParameters = new TArraySizes;
*typeParameters = s;
}
void transferTypeParameters(TArraySizes* s)
{
// For setting an already allocated set of sizes that this type can use
// (no copy made).
typeParameters = s;
}
void clearTypeParameters()
{
typeParameters = nullptr;
}
// Add inner array sizes, to any existing sizes, via copy; the
// sizes passed in can still be reused for other purposes.
void copyTypeParametersInnerSizes(const TArraySizes* s)
{
if (s != nullptr) {
if (typeParameters == nullptr)
copyTypeParameters(*s);
else
typeParameters->addInnerSizes(*s);
}
}
const char* getBasicString() const
{
return TType::getBasicString(basicType);
@ -1919,6 +1983,15 @@ public:
}
}
}
if (isParameterized()) {
appendStr("<");
for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) {
appendInt(typeParameters->getDimSize(i));
if (i != (int)typeParameters->getNumDims() - 1)
appendStr(", ");
}
appendStr(">");
}
if (qualifier.precision != EpqNone) {
appendStr(" ");
appendStr(getPrecisionQualifierString());
@ -2075,6 +2148,13 @@ public:
return arraySizes->sameInnerArrayness(*right.arraySizes);
}
// See if two type's parameters match
bool sameTypeParameters(const TType& right) const
{
return ((typeParameters == nullptr && right.typeParameters == nullptr) ||
(typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
}
// See if two type's elements match in all ways except basic type
bool sameElementShape(const TType& right) const
{
@ -2083,14 +2163,23 @@ public:
matrixCols == right.matrixCols &&
matrixRows == right.matrixRows &&
vector1 == right.vector1 &&
coopmat == right.coopmat &&
sameStructType(right) &&
sameReferenceType(right);
}
// See if a cooperative matrix type parameter with unspecified parameters is
// an OK function parameter
bool coopMatParameterOK(const TType& right) const
{
return coopmat && right.coopmat &&
typeParameters == nullptr && right.typeParameters != nullptr;
}
// See if two types match in all ways (just the actual type, not qualification)
bool operator==(const TType& right) const
{
return sameElementType(right) && sameArrayness(right);
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
}
bool operator!=(const TType& right) const
@ -2115,6 +2204,11 @@ protected:
*arraySizes = *copyOf.arraySizes;
}
if (copyOf.typeParameters) {
typeParameters = new TArraySizes;
*typeParameters = *copyOf.typeParameters;
}
if (copyOf.isStruct() && copyOf.structure) {
auto prevCopy = copiedMap.find(copyOf.structure);
if (prevCopy != copiedMap.end())
@ -2150,6 +2244,7 @@ protected:
// functionality is added.
// HLSL does have a 1-component vectors, so this will be true to disambiguate
// from a scalar.
bool coopmat : 1;
TQualifier qualifier;
TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
@ -2162,6 +2257,7 @@ protected:
TString *fieldName; // for structure field names
TString *typeName; // for structure type name
TSampler sampler;
TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types
};
} // end namespace glslang

View File

@ -254,7 +254,9 @@ struct TArraySizes {
void addInnerSize() { addInnerSize((unsigned)UnsizedArraySize); }
void addInnerSize(int s) { addInnerSize((unsigned)s, nullptr); }
void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); }
void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); }
void addInnerSize(TArraySize pair) {
sizes.push_back(pair.size, pair.node);
}
void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); }
void changeOuterSize(int s) { sizes.changeFront((unsigned)s); }
int getImplicitSize() const { return implicitArraySize; }
@ -318,8 +320,8 @@ struct TArraySizes {
void setVariablyIndexed() { variablyIndexed = true; }
bool isVariablyIndexed() const { return variablyIndexed; }
bool operator==(const TArraySizes& rhs) { return sizes == rhs.sizes; }
bool operator!=(const TArraySizes& rhs) { return sizes != rhs.sizes; }
bool operator==(const TArraySizes& rhs) const { return sizes == rhs.sizes; }
bool operator!=(const TArraySizes& rhs) const { return sizes != rhs.sizes; }
protected:
TSmallArrayVector sizes;

View File

@ -615,6 +615,10 @@ enum TOperator {
EOpAny,
EOpAll,
EOpCooperativeMatrixLoad,
EOpCooperativeMatrixStore,
EOpCooperativeMatrixMulAdd,
//
// Branch
//
@ -737,6 +741,7 @@ enum TOperator {
EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST
EOpConstructReference,
EOpConstructCooperativeMatrix,
EOpConstructGuardEnd,
//

4
glslang/MachineIndependent/Constant.cpp Executable file → Normal file
View File

@ -1354,7 +1354,9 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons
// arrays, vectors, matrices, all use simple multiplicative math
// while structures need to add up heterogeneous members
int start;
if (node->isArray() || ! node->isStruct())
if (node->getType().isCoopMat())
start = 0;
else if (node->isArray() || ! node->isStruct())
start = size * index;
else {
// it is a structure

36
glslang/MachineIndependent/Initialize.cpp Executable file → Normal file
View File

@ -4928,6 +4928,34 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
commonBuiltins.append("void controlBarrier(int, int, int, int);\n"
"void memoryBarrier(int, int, int);\n");
if (profile != EEsProfile && version >= 450) {
// coopMatStoreNV perhaps ought to have "out" on the buf parameter, but
// adding it introduces undesirable tempArgs on the stack. What we want
// is more like "buf" thought of as a pointer value being an in parameter.
stageBuiltins[EShLangCompute].append(
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatLoadNV(out fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent float16_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent float[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent float64_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uint8_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uint16_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uint[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uint64_t[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec2[] buf, uint element, uint stride, bool colMajor);\n"
"void coopMatStoreNV(fcoopmatNV m, volatile coherent uvec4[] buf, uint element, uint stride, bool colMajor);\n"
"fcoopmatNV coopMatMulAddNV(fcoopmatNV A, fcoopmatNV B, fcoopmatNV C);\n"
);
}
//============================================================================
//
// Prototypes for built-in functions seen by fragment shaders only.
@ -8658,6 +8686,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("subgroupMemoryBarrierShared", 1, &E_GL_KHR_shader_subgroup_basic);
}
symbolTable.setFunctionExtensions("coopMatLoadNV", 1, &E_GL_NV_cooperative_matrix);
symbolTable.setFunctionExtensions("coopMatStoreNV", 1, &E_GL_NV_cooperative_matrix);
symbolTable.setFunctionExtensions("coopMatMulAddNV", 1, &E_GL_NV_cooperative_matrix);
break;
#ifdef NV_EXTENSIONS
case EShLangRayGenNV:
@ -9462,6 +9495,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("fwidthCoarse",EOpFwidthCoarse);
}
#endif
symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoad);
symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStore);
symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd);
break;
#ifdef NV_EXTENSIONS

47
glslang/MachineIndependent/Intermediate.cpp Executable file → Normal file
View File

@ -725,6 +725,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
return newNode;
}
TIntermTyped* TIntermediate::addConversion(TBasicType convertTo, TIntermTyped* node) const
{
return createConversion(convertTo, node);
}
// For converting a pair of operands to a binary operation to compatible
// types with each other, relative to the operation in 'op'.
// This does not cover assignment operations, which is asymmetric in that the
@ -751,6 +756,10 @@ TIntermediate::addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* no
// If differing arrays, then no conversions.
if (node0->getType().isArray() || node1->getType().isArray())
return std::make_tuple(nullptr, nullptr);
// No implicit conversions for operations involving cooperative matrices
if (node0->getType().isCoopMat() || node1->getType().isCoopMat())
return std::make_tuple(node0, node1);
}
auto promoteTo = std::make_tuple(EbtNumTypes, EbtNumTypes);
@ -983,6 +992,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpSequence:
case EOpConstructStruct:
case EOpConstructCooperativeMatrix:
if (type.getBasicType() == EbtReference || node->getType().getBasicType() == EbtReference) {
// types must match to assign a reference
@ -1847,6 +1857,9 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
if (type.getQualifier().nonUniform)
return EOpConstructNonuniform;
if (type.isCoopMat())
return EOpConstructCooperativeMatrix;
switch (type.getBasicType()) {
case EbtStruct:
op = EOpConstructStruct;
@ -3319,6 +3332,40 @@ bool TIntermediate::promoteBinary(TIntermBinary& node)
break;
}
if (left->getType().isCoopMat() || right->getType().isCoopMat()) {
if (left->getType().isCoopMat() && right->getType().isCoopMat() &&
*left->getType().getTypeParameters() != *right->getType().getTypeParameters()) {
return false;
}
switch (op) {
case EOpMul:
case EOpMulAssign:
if (left->getType().isCoopMat() && right->getType().isCoopMat()) {
return false;
}
if (op == EOpMulAssign && right->getType().isCoopMat()) {
return false;
}
node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar);
if (right->getType().isCoopMat()) {
node.setType(right->getType());
}
return true;
case EOpAdd:
case EOpSub:
case EOpDiv:
case EOpAssign:
// These require both to be cooperative matrices
if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) {
return false;
}
return true;
default:
break;
}
return false;
}
// Finish handling the case, for all ops, where both operands are scalars.
if (left->isScalar() && right->isScalar())
return true;

138
glslang/MachineIndependent/ParseHelper.cpp Executable file → Normal file
View File

@ -275,6 +275,12 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
if (tokens.size() != 1)
error(loc, "extra tokens", "#pragma", "");
intermediate.setUseVulkanMemoryModel();
} else if (spvVersion.spv > 0 && tokens[0].compare("use_variable_pointers") == 0) {
if (tokens.size() != 1)
error(loc, "extra tokens", "#pragma", "");
if (spvVersion.spv < glslang::EShTargetSpv_1_3)
error(loc, "requires SPIR-V 1.3", "#pragma use_variable_pointers", "");
intermediate.setUseVariablePointers();
} else if (tokens[0].compare("once") == 0) {
warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
@ -371,7 +377,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn
// basic type checks...
variableCheck(base);
if (! base->isArray() && ! base->isMatrix() && ! base->isVector()) {
if (! base->isArray() && ! base->isMatrix() && ! base->isVector() && ! base->getType().isCoopMat()) {
if (base->getAsSymbolNode())
error(loc, " left of '[' is not of type array, matrix, or vector ", base->getAsSymbolNode()->getName().c_str(), "");
else
@ -767,7 +773,7 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
const char* feature = ".length() on vectors and matrices";
requireProfile(loc, ~EEsProfile, feature);
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature);
} else {
} else if (!base->getType().isCoopMat()) {
error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str());
return base;
@ -784,6 +790,11 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm
return base;
}
if (base->getType().isCoopMat()) {
error(loc, "cannot apply to a cooperative matrix type:", ".", field.c_str());
return base;
}
// It's neither an array nor .length() if we get here,
// leaving swizzles and struct/block dereferences.
@ -1204,6 +1215,13 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
}
result = addOutputArgumentConversions(*fnCandidate, *result->getAsAggregate());
}
if (result->getAsTyped()->getType().isCoopMat() &&
!result->getAsTyped()->getType().isParameterized()) {
assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd);
result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType());
}
}
}
@ -1430,6 +1448,8 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction
length = type.getMatrixCols();
else if (type.isVector())
length = type.getVectorSize();
else if (type.isCoopMat())
return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
else {
// we should not get here, because earlier semantic checking should have prevented this path
error(loc, ".length()", "unexpected use of .length()", "");
@ -1456,7 +1476,8 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte
// means take 'arguments' itself as the one argument.
TIntermTyped* arg = function.getParamCount() == 1 ? arguments->getAsTyped() : (aggregate ? aggregate->getSequence()[i]->getAsTyped() : arguments->getAsTyped());
if (*function[i].type != arg->getType()) {
if (function[i].type->getQualifier().isParamInput()) {
if (function[i].type->getQualifier().isParamInput() &&
!function[i].type->isCoopMat()) {
// In-qualified arguments just need an extra node added above the argument to
// convert to the correct type.
arg = intermediate.addConversion(EOpFunctionCall, *function[i].type, arg);
@ -1524,7 +1545,14 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
if (function[i].type->getQualifier().isParamOutput()) {
// Out-qualified arguments need to use the topology set up above.
// do the " ...(tempArg, ...), arg = tempArg" bit from above
TVariable* tempArg = makeInternalVariable("tempArg", *function[i].type);
TType paramType;
paramType.shallowCopy(*function[i].type);
if (arguments[i]->getAsTyped()->getType().isParameterized() &&
!paramType.isParameterized()) {
paramType.shallowCopy(arguments[i]->getAsTyped()->getType());
paramType.copyTypeParameters(*arguments[i]->getAsTyped()->getType().getTypeParameters());
}
TVariable* tempArg = makeInternalVariable("tempArg", paramType);
tempArg->getWritableType().getQualifier().makeTemporary();
TIntermSymbol* tempArgNode = intermediate.addSymbol(*tempArg, intermNode.getLoc());
TIntermTyped* tempAssign = intermediate.addAssign(EOpAssign, arguments[i]->getAsTyped(), tempArgNode, arguments[i]->getLoc());
@ -2913,6 +2941,16 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T
return true;
}
if (type.isCoopMat() && function.getParamCount() != 1) {
error(loc, "wrong number of arguments", "constructor", "");
return true;
}
if (type.isCoopMat() &&
!(function[0].type->isScalar() || function[0].type->isCoopMat())) {
error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", "");
return true;
}
TIntermTyped* typed = node->getAsTyped();
if (typed == nullptr) {
error(loc, "constructor argument does not have a type", "constructor", "");
@ -3534,7 +3572,7 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas
//
// Do size checking for an array type's size.
//
void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair)
void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType)
{
bool isConst = false;
sizePair.node = nullptr;
@ -3554,18 +3592,24 @@ void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TA
TIntermSymbol* symbol = expr->getAsSymbolNode();
if (symbol && symbol->getConstArray().size() > 0)
size = symbol->getConstArray()[0].getIConst();
} else if (expr->getAsUnaryNode() &&
expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength &&
expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) {
isConst = true;
size = 1;
sizePair.node = expr->getAsUnaryNode();
}
}
sizePair.size = size;
if (! isConst || (expr->getBasicType() != EbtInt && expr->getBasicType() != EbtUint)) {
error(loc, "array size must be a constant integer expression", "", "");
error(loc, sizeType, "", "must be a constant integer expression");
return;
}
if (size <= 0) {
error(loc, "array size must be a positive integer", "", "");
error(loc, sizeType, "", "must be a positive integer");
return;
}
}
@ -3623,7 +3667,7 @@ bool TParseContext::arrayError(const TSourceLoc& loc, const TType& type)
//
void TParseContext::arraySizeRequiredCheck(const TSourceLoc& loc, const TArraySizes& arraySizes)
{
if (arraySizes.hasUnsized())
if (!parsingBuiltins && arraySizes.hasUnsized())
error(loc, "array size required", "", "");
}
@ -3660,7 +3704,8 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua
arraySizes->clearInnerUnsized();
}
if (arraySizes->isInnerSpecialization())
if (arraySizes->isInnerSpecialization() &&
(qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst))
error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
// desktop always allows outer-dimension-unsized variable arrays,
@ -6035,9 +6080,18 @@ const TFunction* TParseContext::findFunction400(const TSourceLoc& loc, const TFu
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
// can 'from' convert to 'to'?
const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool {
const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
if (from == to)
return true;
if (from.coopMatParameterOK(to))
return true;
// Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
if (builtIn && from.isArray() && to.isUnsizedArray()) {
TType fromElementType(from, 0);
TType toElementType(to, 0);
if (fromElementType == toElementType)
return true;
}
if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
return false;
return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
@ -6100,9 +6154,18 @@ const TFunction* TParseContext::findFunctionExplicitTypes(const TSourceLoc& loc,
symbolTable.findFunctionNameList(call.getMangledName(), candidateList, builtIn);
// can 'from' convert to 'to'?
const auto convertible = [this](const TType& from, const TType& to, TOperator, int) -> bool {
const auto convertible = [this,builtIn](const TType& from, const TType& to, TOperator, int) -> bool {
if (from == to)
return true;
if (from.coopMatParameterOK(to))
return true;
// Allow a sized array to be passed through an unsized array parameter, for coopMatLoad/Store functions
if (builtIn && from.isArray() && to.isUnsizedArray()) {
TType fromElementType(from, 0);
TType toElementType(to, 0);
if (fromElementType == toElementType)
return true;
}
if (from.isArray() || to.isArray() || ! from.sameElementShape(to))
return false;
return intermediate.canImplicitlyPromote(from.getBasicType(), to.getBasicType());
@ -6194,6 +6257,25 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
type.copyArrayInnerSizes(publicType.arraySizes);
arrayOfArrayVersionCheck(loc, type.getArraySizes());
if (type.isCoopMat()) {
intermediate.setUseVulkanMemoryModel();
intermediate.setUseStorageBuffer();
if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) {
error(loc, "expected four type parameters", identifier.c_str(), "");
}
if (publicType.typeParameters &&
publicType.typeParameters->getDimSize(0) != 16 &&
publicType.typeParameters->getDimSize(0) != 32 &&
publicType.typeParameters->getDimSize(0) != 64) {
error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), "");
}
} else {
if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) {
error(loc, "unexpected type parameters", identifier.c_str(), "");
}
}
if (voidErrorCheck(loc, identifier, type.getBasicType()))
return nullptr;
@ -6218,6 +6300,10 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage");
}
if (type.getQualifier().storage == EvqShared &&
type.containsCoopMat())
error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", "");
if (identifier != "gl_FragCoord" && (publicType.shaderQualifiers.originUpperLeft || publicType.shaderQualifiers.pixelCenterInteger))
error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", "");
if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.layoutDepth != EldNone)
@ -6809,6 +6895,33 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
return nullptr;
}
case EOpConstructCooperativeMatrix:
if (!node->getType().isCoopMat()) {
if (type.getBasicType() != node->getType().getBasicType()) {
node = intermediate.addConversion(type.getBasicType(), node);
}
node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc());
} else {
switch (type.getBasicType()) {
default:
assert(0);
break;
case EbtFloat:
assert(node->getType().getBasicType() == EbtFloat16);
node = intermediate.addUnaryNode(EOpConvFloat16ToFloat, node, node->getLoc(), type);
break;
case EbtFloat16:
assert(node->getType().getBasicType() == EbtFloat);
node = intermediate.addUnaryNode(EOpConvFloatToFloat16, node, node->getLoc(), type);
break;
}
// If it's a (non-specialization) constant, it must be folded.
if (node->getAsUnaryNode()->getOperand()->getAsConstantUnion())
return node->getAsUnaryNode()->getOperand()->getAsConstantUnion()->fold(op, node->getType());
}
return node;
default:
error(loc, "unsupported construction", "", "");
@ -6895,6 +7008,9 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
if (memberType.containsOpaque())
error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), "");
if (memberType.containsCoopMat())
error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), "");
}
// This might be a redeclaration of a built-in block. If so, redeclareBuiltinBlock() will

2
glslang/MachineIndependent/ParseHelper.h Executable file → Normal file
View File

@ -337,7 +337,7 @@ public:
void globalCheck(const TSourceLoc&, const char* token);
bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&);
bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&);
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&);
void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType);
bool arrayQualifierError(const TSourceLoc&, const TQualifier&);
bool arrayError(const TSourceLoc&, const TType&);
void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&);

View File

@ -714,6 +714,8 @@ void TScanContext::fillInKeywordMap()
(*KeywordMap)["taskNV"] = PERTASKNV;
#endif
(*KeywordMap)["fcoopmatNV"] = FCOOPMATNV;
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
ReservedSet->insert("common");
@ -1612,6 +1614,13 @@ int TScanContext::tokenizeIdentifier()
return identifierOrType();
#endif
case FCOOPMATNV:
afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_NV_cooperative_matrix))
return keyword;
return identifierOrType();
default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
return 0;

12
glslang/MachineIndependent/Versions.cpp Executable file → Normal file
View File

@ -248,6 +248,8 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable;
#endif
extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable;
// AEP
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
extensionBehavior[E_GL_KHR_blend_equation_advanced] = EBhDisable;
@ -427,6 +429,8 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_NV_shader_texture_footprint 1\n"
"#define GL_NV_mesh_shader 1\n"
#endif
"#define GL_NV_cooperative_matrix 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
"#define GL_EXT_shader_explicit_arithmetic_types_int16 1\n"
@ -1083,6 +1087,14 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil
}
}
void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {E_GL_NV_cooperative_matrix};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
// Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
{

View File

@ -225,6 +225,8 @@ const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
#endif
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
// AEP
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
const char* const E_GL_KHR_blend_equation_advanced = "GL_KHR_blend_equation_advanced";

58
glslang/MachineIndependent/glslang.y Executable file → Normal file
View File

@ -100,6 +100,7 @@ using namespace glslang;
glslang::TArraySizes* arraySizes;
glslang::TIdentifierList* identifierList;
};
glslang::TArraySizes* typeParameters;
} interm;
}
@ -166,6 +167,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> F64MAT4X2 F64MAT4X3 F64MAT4X4
%token <lex> ATOMIC_UINT
%token <lex> ACCSTRUCTNV
%token <lex> FCOOPMATNV
// combined image/sampler
%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
@ -273,6 +275,10 @@ extern int yylex(YYSTYPE*, TParseContext&);
%type <interm.type> layout_qualifier layout_qualifier_id_list layout_qualifier_id
%type <interm.type> non_uniform_qualifier
%type <interm.typeParameters> type_parameter_specifier
%type <interm.typeParameters> type_parameter_specifier_opt
%type <interm.typeParameters> type_parameter_specifier_list
%type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> single_type_qualifier
%type <interm.type> type_specifier_nonarray
@ -1487,15 +1493,17 @@ type_name_list
;
type_specifier
: type_specifier_nonarray {
: type_specifier_nonarray type_parameter_specifier_opt {
$$ = $1;
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
$$.typeParameters = $2;
}
| type_specifier_nonarray array_specifier {
parseContext.arrayOfArrayVersionCheck($2.loc, $2.arraySizes);
| type_specifier_nonarray type_parameter_specifier_opt array_specifier {
parseContext.arrayOfArrayVersionCheck($3.loc, $3.arraySizes);
$$ = $1;
$$.qualifier.precision = parseContext.getDefaultPrecision($$);
$$.arraySizes = $2.arraySizes;
$$.typeParameters = $2;
$$.arraySizes = $3.arraySizes;
}
;
@ -1510,7 +1518,7 @@ array_specifier
$$.arraySizes = new TArraySizes;
TArraySize size;
parseContext.arraySizeCheck($2->getLoc(), $2, size);
parseContext.arraySizeCheck($2->getLoc(), $2, size, "array size");
$$.arraySizes->addInnerSize(size);
}
| array_specifier LEFT_BRACKET RIGHT_BRACKET {
@ -1521,11 +1529,43 @@ array_specifier
$$ = $1;
TArraySize size;
parseContext.arraySizeCheck($3->getLoc(), $3, size);
parseContext.arraySizeCheck($3->getLoc(), $3, size, "array size");
$$.arraySizes->addInnerSize(size);
}
;
type_parameter_specifier_opt
: type_parameter_specifier {
$$ = $1;
}
| /* May be null */ {
$$ = 0;
}
;
type_parameter_specifier
: LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE {
$$ = $2;
}
;
type_parameter_specifier_list
: unary_expression {
$$ = new TArraySizes;
TArraySize size;
parseContext.arraySizeCheck($1->getLoc(), $1, size, "type parameter");
$$->addInnerSize(size);
}
| type_parameter_specifier_list COMMA unary_expression {
$$ = $1;
TArraySize size;
parseContext.arraySizeCheck($3->getLoc(), $3, size, "type parameter");
$$->addInnerSize(size);
}
;
type_specifier_nonarray
: VOID {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
@ -3172,6 +3212,12 @@ type_specifier_nonarray
$$.basicType = EbtSampler;
$$.sampler.setSubpass(EbtUint, true);
}
| FCOOPMATNV {
parseContext.fcoopmatCheck($1.loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtFloat;
$$.coopmat = true;
}
| struct_specifier {
$$ = $1;
$$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;

File diff suppressed because it is too large Load Diff

View File

@ -220,235 +220,236 @@ extern int yydebug;
F64MAT4X4 = 430,
ATOMIC_UINT = 431,
ACCSTRUCTNV = 432,
SAMPLER1D = 433,
SAMPLER2D = 434,
SAMPLER3D = 435,
SAMPLERCUBE = 436,
SAMPLER1DSHADOW = 437,
SAMPLER2DSHADOW = 438,
SAMPLERCUBESHADOW = 439,
SAMPLER1DARRAY = 440,
SAMPLER2DARRAY = 441,
SAMPLER1DARRAYSHADOW = 442,
SAMPLER2DARRAYSHADOW = 443,
ISAMPLER1D = 444,
ISAMPLER2D = 445,
ISAMPLER3D = 446,
ISAMPLERCUBE = 447,
ISAMPLER1DARRAY = 448,
ISAMPLER2DARRAY = 449,
USAMPLER1D = 450,
USAMPLER2D = 451,
USAMPLER3D = 452,
USAMPLERCUBE = 453,
USAMPLER1DARRAY = 454,
USAMPLER2DARRAY = 455,
SAMPLER2DRECT = 456,
SAMPLER2DRECTSHADOW = 457,
ISAMPLER2DRECT = 458,
USAMPLER2DRECT = 459,
SAMPLERBUFFER = 460,
ISAMPLERBUFFER = 461,
USAMPLERBUFFER = 462,
SAMPLERCUBEARRAY = 463,
SAMPLERCUBEARRAYSHADOW = 464,
ISAMPLERCUBEARRAY = 465,
USAMPLERCUBEARRAY = 466,
SAMPLER2DMS = 467,
ISAMPLER2DMS = 468,
USAMPLER2DMS = 469,
SAMPLER2DMSARRAY = 470,
ISAMPLER2DMSARRAY = 471,
USAMPLER2DMSARRAY = 472,
SAMPLEREXTERNALOES = 473,
SAMPLEREXTERNAL2DY2YEXT = 474,
F16SAMPLER1D = 475,
F16SAMPLER2D = 476,
F16SAMPLER3D = 477,
F16SAMPLER2DRECT = 478,
F16SAMPLERCUBE = 479,
F16SAMPLER1DARRAY = 480,
F16SAMPLER2DARRAY = 481,
F16SAMPLERCUBEARRAY = 482,
F16SAMPLERBUFFER = 483,
F16SAMPLER2DMS = 484,
F16SAMPLER2DMSARRAY = 485,
F16SAMPLER1DSHADOW = 486,
F16SAMPLER2DSHADOW = 487,
F16SAMPLER1DARRAYSHADOW = 488,
F16SAMPLER2DARRAYSHADOW = 489,
F16SAMPLER2DRECTSHADOW = 490,
F16SAMPLERCUBESHADOW = 491,
F16SAMPLERCUBEARRAYSHADOW = 492,
SAMPLER = 493,
SAMPLERSHADOW = 494,
TEXTURE1D = 495,
TEXTURE2D = 496,
TEXTURE3D = 497,
TEXTURECUBE = 498,
TEXTURE1DARRAY = 499,
TEXTURE2DARRAY = 500,
ITEXTURE1D = 501,
ITEXTURE2D = 502,
ITEXTURE3D = 503,
ITEXTURECUBE = 504,
ITEXTURE1DARRAY = 505,
ITEXTURE2DARRAY = 506,
UTEXTURE1D = 507,
UTEXTURE2D = 508,
UTEXTURE3D = 509,
UTEXTURECUBE = 510,
UTEXTURE1DARRAY = 511,
UTEXTURE2DARRAY = 512,
TEXTURE2DRECT = 513,
ITEXTURE2DRECT = 514,
UTEXTURE2DRECT = 515,
TEXTUREBUFFER = 516,
ITEXTUREBUFFER = 517,
UTEXTUREBUFFER = 518,
TEXTURECUBEARRAY = 519,
ITEXTURECUBEARRAY = 520,
UTEXTURECUBEARRAY = 521,
TEXTURE2DMS = 522,
ITEXTURE2DMS = 523,
UTEXTURE2DMS = 524,
TEXTURE2DMSARRAY = 525,
ITEXTURE2DMSARRAY = 526,
UTEXTURE2DMSARRAY = 527,
F16TEXTURE1D = 528,
F16TEXTURE2D = 529,
F16TEXTURE3D = 530,
F16TEXTURE2DRECT = 531,
F16TEXTURECUBE = 532,
F16TEXTURE1DARRAY = 533,
F16TEXTURE2DARRAY = 534,
F16TEXTURECUBEARRAY = 535,
F16TEXTUREBUFFER = 536,
F16TEXTURE2DMS = 537,
F16TEXTURE2DMSARRAY = 538,
SUBPASSINPUT = 539,
SUBPASSINPUTMS = 540,
ISUBPASSINPUT = 541,
ISUBPASSINPUTMS = 542,
USUBPASSINPUT = 543,
USUBPASSINPUTMS = 544,
F16SUBPASSINPUT = 545,
F16SUBPASSINPUTMS = 546,
IMAGE1D = 547,
IIMAGE1D = 548,
UIMAGE1D = 549,
IMAGE2D = 550,
IIMAGE2D = 551,
UIMAGE2D = 552,
IMAGE3D = 553,
IIMAGE3D = 554,
UIMAGE3D = 555,
IMAGE2DRECT = 556,
IIMAGE2DRECT = 557,
UIMAGE2DRECT = 558,
IMAGECUBE = 559,
IIMAGECUBE = 560,
UIMAGECUBE = 561,
IMAGEBUFFER = 562,
IIMAGEBUFFER = 563,
UIMAGEBUFFER = 564,
IMAGE1DARRAY = 565,
IIMAGE1DARRAY = 566,
UIMAGE1DARRAY = 567,
IMAGE2DARRAY = 568,
IIMAGE2DARRAY = 569,
UIMAGE2DARRAY = 570,
IMAGECUBEARRAY = 571,
IIMAGECUBEARRAY = 572,
UIMAGECUBEARRAY = 573,
IMAGE2DMS = 574,
IIMAGE2DMS = 575,
UIMAGE2DMS = 576,
IMAGE2DMSARRAY = 577,
IIMAGE2DMSARRAY = 578,
UIMAGE2DMSARRAY = 579,
F16IMAGE1D = 580,
F16IMAGE2D = 581,
F16IMAGE3D = 582,
F16IMAGE2DRECT = 583,
F16IMAGECUBE = 584,
F16IMAGE1DARRAY = 585,
F16IMAGE2DARRAY = 586,
F16IMAGECUBEARRAY = 587,
F16IMAGEBUFFER = 588,
F16IMAGE2DMS = 589,
F16IMAGE2DMSARRAY = 590,
STRUCT = 591,
VOID = 592,
WHILE = 593,
IDENTIFIER = 594,
TYPE_NAME = 595,
FLOATCONSTANT = 596,
DOUBLECONSTANT = 597,
INT16CONSTANT = 598,
UINT16CONSTANT = 599,
INT32CONSTANT = 600,
UINT32CONSTANT = 601,
INTCONSTANT = 602,
UINTCONSTANT = 603,
INT64CONSTANT = 604,
UINT64CONSTANT = 605,
BOOLCONSTANT = 606,
FLOAT16CONSTANT = 607,
LEFT_OP = 608,
RIGHT_OP = 609,
INC_OP = 610,
DEC_OP = 611,
LE_OP = 612,
GE_OP = 613,
EQ_OP = 614,
NE_OP = 615,
AND_OP = 616,
OR_OP = 617,
XOR_OP = 618,
MUL_ASSIGN = 619,
DIV_ASSIGN = 620,
ADD_ASSIGN = 621,
MOD_ASSIGN = 622,
LEFT_ASSIGN = 623,
RIGHT_ASSIGN = 624,
AND_ASSIGN = 625,
XOR_ASSIGN = 626,
OR_ASSIGN = 627,
SUB_ASSIGN = 628,
LEFT_PAREN = 629,
RIGHT_PAREN = 630,
LEFT_BRACKET = 631,
RIGHT_BRACKET = 632,
LEFT_BRACE = 633,
RIGHT_BRACE = 634,
DOT = 635,
COMMA = 636,
COLON = 637,
EQUAL = 638,
SEMICOLON = 639,
BANG = 640,
DASH = 641,
TILDE = 642,
PLUS = 643,
STAR = 644,
SLASH = 645,
PERCENT = 646,
LEFT_ANGLE = 647,
RIGHT_ANGLE = 648,
VERTICAL_BAR = 649,
CARET = 650,
AMPERSAND = 651,
QUESTION = 652,
INVARIANT = 653,
PRECISE = 654,
HIGH_PRECISION = 655,
MEDIUM_PRECISION = 656,
LOW_PRECISION = 657,
PRECISION = 658,
PACKED = 659,
RESOURCE = 660,
SUPERP = 661
FCOOPMATNV = 433,
SAMPLER1D = 434,
SAMPLER2D = 435,
SAMPLER3D = 436,
SAMPLERCUBE = 437,
SAMPLER1DSHADOW = 438,
SAMPLER2DSHADOW = 439,
SAMPLERCUBESHADOW = 440,
SAMPLER1DARRAY = 441,
SAMPLER2DARRAY = 442,
SAMPLER1DARRAYSHADOW = 443,
SAMPLER2DARRAYSHADOW = 444,
ISAMPLER1D = 445,
ISAMPLER2D = 446,
ISAMPLER3D = 447,
ISAMPLERCUBE = 448,
ISAMPLER1DARRAY = 449,
ISAMPLER2DARRAY = 450,
USAMPLER1D = 451,
USAMPLER2D = 452,
USAMPLER3D = 453,
USAMPLERCUBE = 454,
USAMPLER1DARRAY = 455,
USAMPLER2DARRAY = 456,
SAMPLER2DRECT = 457,
SAMPLER2DRECTSHADOW = 458,
ISAMPLER2DRECT = 459,
USAMPLER2DRECT = 460,
SAMPLERBUFFER = 461,
ISAMPLERBUFFER = 462,
USAMPLERBUFFER = 463,
SAMPLERCUBEARRAY = 464,
SAMPLERCUBEARRAYSHADOW = 465,
ISAMPLERCUBEARRAY = 466,
USAMPLERCUBEARRAY = 467,
SAMPLER2DMS = 468,
ISAMPLER2DMS = 469,
USAMPLER2DMS = 470,
SAMPLER2DMSARRAY = 471,
ISAMPLER2DMSARRAY = 472,
USAMPLER2DMSARRAY = 473,
SAMPLEREXTERNALOES = 474,
SAMPLEREXTERNAL2DY2YEXT = 475,
F16SAMPLER1D = 476,
F16SAMPLER2D = 477,
F16SAMPLER3D = 478,
F16SAMPLER2DRECT = 479,
F16SAMPLERCUBE = 480,
F16SAMPLER1DARRAY = 481,
F16SAMPLER2DARRAY = 482,
F16SAMPLERCUBEARRAY = 483,
F16SAMPLERBUFFER = 484,
F16SAMPLER2DMS = 485,
F16SAMPLER2DMSARRAY = 486,
F16SAMPLER1DSHADOW = 487,
F16SAMPLER2DSHADOW = 488,
F16SAMPLER1DARRAYSHADOW = 489,
F16SAMPLER2DARRAYSHADOW = 490,
F16SAMPLER2DRECTSHADOW = 491,
F16SAMPLERCUBESHADOW = 492,
F16SAMPLERCUBEARRAYSHADOW = 493,
SAMPLER = 494,
SAMPLERSHADOW = 495,
TEXTURE1D = 496,
TEXTURE2D = 497,
TEXTURE3D = 498,
TEXTURECUBE = 499,
TEXTURE1DARRAY = 500,
TEXTURE2DARRAY = 501,
ITEXTURE1D = 502,
ITEXTURE2D = 503,
ITEXTURE3D = 504,
ITEXTURECUBE = 505,
ITEXTURE1DARRAY = 506,
ITEXTURE2DARRAY = 507,
UTEXTURE1D = 508,
UTEXTURE2D = 509,
UTEXTURE3D = 510,
UTEXTURECUBE = 511,
UTEXTURE1DARRAY = 512,
UTEXTURE2DARRAY = 513,
TEXTURE2DRECT = 514,
ITEXTURE2DRECT = 515,
UTEXTURE2DRECT = 516,
TEXTUREBUFFER = 517,
ITEXTUREBUFFER = 518,
UTEXTUREBUFFER = 519,
TEXTURECUBEARRAY = 520,
ITEXTURECUBEARRAY = 521,
UTEXTURECUBEARRAY = 522,
TEXTURE2DMS = 523,
ITEXTURE2DMS = 524,
UTEXTURE2DMS = 525,
TEXTURE2DMSARRAY = 526,
ITEXTURE2DMSARRAY = 527,
UTEXTURE2DMSARRAY = 528,
F16TEXTURE1D = 529,
F16TEXTURE2D = 530,
F16TEXTURE3D = 531,
F16TEXTURE2DRECT = 532,
F16TEXTURECUBE = 533,
F16TEXTURE1DARRAY = 534,
F16TEXTURE2DARRAY = 535,
F16TEXTURECUBEARRAY = 536,
F16TEXTUREBUFFER = 537,
F16TEXTURE2DMS = 538,
F16TEXTURE2DMSARRAY = 539,
SUBPASSINPUT = 540,
SUBPASSINPUTMS = 541,
ISUBPASSINPUT = 542,
ISUBPASSINPUTMS = 543,
USUBPASSINPUT = 544,
USUBPASSINPUTMS = 545,
F16SUBPASSINPUT = 546,
F16SUBPASSINPUTMS = 547,
IMAGE1D = 548,
IIMAGE1D = 549,
UIMAGE1D = 550,
IMAGE2D = 551,
IIMAGE2D = 552,
UIMAGE2D = 553,
IMAGE3D = 554,
IIMAGE3D = 555,
UIMAGE3D = 556,
IMAGE2DRECT = 557,
IIMAGE2DRECT = 558,
UIMAGE2DRECT = 559,
IMAGECUBE = 560,
IIMAGECUBE = 561,
UIMAGECUBE = 562,
IMAGEBUFFER = 563,
IIMAGEBUFFER = 564,
UIMAGEBUFFER = 565,
IMAGE1DARRAY = 566,
IIMAGE1DARRAY = 567,
UIMAGE1DARRAY = 568,
IMAGE2DARRAY = 569,
IIMAGE2DARRAY = 570,
UIMAGE2DARRAY = 571,
IMAGECUBEARRAY = 572,
IIMAGECUBEARRAY = 573,
UIMAGECUBEARRAY = 574,
IMAGE2DMS = 575,
IIMAGE2DMS = 576,
UIMAGE2DMS = 577,
IMAGE2DMSARRAY = 578,
IIMAGE2DMSARRAY = 579,
UIMAGE2DMSARRAY = 580,
F16IMAGE1D = 581,
F16IMAGE2D = 582,
F16IMAGE3D = 583,
F16IMAGE2DRECT = 584,
F16IMAGECUBE = 585,
F16IMAGE1DARRAY = 586,
F16IMAGE2DARRAY = 587,
F16IMAGECUBEARRAY = 588,
F16IMAGEBUFFER = 589,
F16IMAGE2DMS = 590,
F16IMAGE2DMSARRAY = 591,
STRUCT = 592,
VOID = 593,
WHILE = 594,
IDENTIFIER = 595,
TYPE_NAME = 596,
FLOATCONSTANT = 597,
DOUBLECONSTANT = 598,
INT16CONSTANT = 599,
UINT16CONSTANT = 600,
INT32CONSTANT = 601,
UINT32CONSTANT = 602,
INTCONSTANT = 603,
UINTCONSTANT = 604,
INT64CONSTANT = 605,
UINT64CONSTANT = 606,
BOOLCONSTANT = 607,
FLOAT16CONSTANT = 608,
LEFT_OP = 609,
RIGHT_OP = 610,
INC_OP = 611,
DEC_OP = 612,
LE_OP = 613,
GE_OP = 614,
EQ_OP = 615,
NE_OP = 616,
AND_OP = 617,
OR_OP = 618,
XOR_OP = 619,
MUL_ASSIGN = 620,
DIV_ASSIGN = 621,
ADD_ASSIGN = 622,
MOD_ASSIGN = 623,
LEFT_ASSIGN = 624,
RIGHT_ASSIGN = 625,
AND_ASSIGN = 626,
XOR_ASSIGN = 627,
OR_ASSIGN = 628,
SUB_ASSIGN = 629,
LEFT_PAREN = 630,
RIGHT_PAREN = 631,
LEFT_BRACKET = 632,
RIGHT_BRACKET = 633,
LEFT_BRACE = 634,
RIGHT_BRACE = 635,
DOT = 636,
COMMA = 637,
COLON = 638,
EQUAL = 639,
SEMICOLON = 640,
BANG = 641,
DASH = 642,
TILDE = 643,
PLUS = 644,
STAR = 645,
SLASH = 646,
PERCENT = 647,
LEFT_ANGLE = 648,
RIGHT_ANGLE = 649,
VERTICAL_BAR = 650,
CARET = 651,
AMPERSAND = 652,
QUESTION = 653,
INVARIANT = 654,
PRECISE = 655,
HIGH_PRECISION = 656,
MEDIUM_PRECISION = 657,
LOW_PRECISION = 658,
PRECISION = 659,
PACKED = 660,
RESOURCE = 661,
SUPERP = 662
};
#endif
@ -490,9 +491,10 @@ union YYSTYPE
glslang::TArraySizes* arraySizes;
glslang::TIdentifierList* identifierList;
};
glslang::TArraySizes* typeParameters;
} interm;
#line 496 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
#line 498 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
};
typedef union YYSTYPE YYSTYPE;

View File

@ -817,6 +817,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructStruct: out.debug << "Construct structure"; break;
case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
case EOpConstructReference: out.debug << "Construct reference"; break;
case EOpConstructCooperativeMatrix: out.debug << "Construct cooperative matrix"; break;
case EOpLessThan: out.debug << "Compare Less Than"; break;
case EOpGreaterThan: out.debug << "Compare Greater Than"; break;
@ -1066,6 +1067,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
#endif
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break;
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
default: out.debug.message(EPrefixError, "Bad aggregation op");
}

View File

@ -261,6 +261,7 @@ public:
useStorageBuffer(false),
useVulkanMemoryModel(false),
hlslIoMapping(false),
useVariablePointers(false),
textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false),
binaryDoubleOutput(false),
@ -405,6 +406,12 @@ public:
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setUseVariablePointers()
{
useVariablePointers = true;
processes.addProcess("use-variable-pointers");
}
bool usingVariablePointers() const { return useVariablePointers; }
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
bool hasCounterBufferName(const TString& name) const {
@ -491,6 +498,7 @@ public:
TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*) const;
std::tuple<TIntermTyped*, TIntermTyped*> addConversion(TOperator op, TIntermTyped* node0, TIntermTyped* node1) const;
TIntermTyped* addUniShapeConversion(TOperator, const TType&, TIntermTyped*);
TIntermTyped* addConversion(TBasicType convertTo, TIntermTyped* node) const;
void addBiShapeConversion(TOperator, TIntermTyped*& lhsNode, TIntermTyped*& rhsNode);
TIntermTyped* addShapeConversion(const TType&, TIntermTyped*);
TIntermTyped* addBinaryMath(TOperator, TIntermTyped* left, TIntermTyped* right, TSourceLoc);
@ -852,6 +860,7 @@ protected:
bool useStorageBuffer;
bool useVulkanMemoryModel;
bool hlslIoMapping;
bool useVariablePointers;
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers

View File

@ -104,6 +104,7 @@ public:
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;

View File

@ -286,6 +286,8 @@ INSTANTIATE_TEST_CASE_P(
"spv.constStruct.vert",
"spv.controlFlowAttributes.frag",
"spv.conversion.frag",
"spv.coopmat.comp",
"spv.coopmat_Error.comp",
"spv.dataOut.frag",
"spv.dataOutIndirect.frag",
"spv.dataOutIndirect.vert",
@ -410,6 +412,7 @@ INSTANTIATE_TEST_CASE_P(
::testing::ValuesIn(std::vector<std::string>({
"spv.1.3.8bitstorage-ubo.vert",
"spv.1.3.8bitstorage-ssbo.vert",
"spv.1.3.coopmat.comp",
"spv.deviceGroup.frag",
"spv.drawParams.vert",
"spv.int8.frag",

View File

@ -5,14 +5,14 @@
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Tools",
"subdir" : "External/spirv-tools",
"commit" : "5994ae2a045015004cce24802dc47c33736486ea"
"commit" : "002ef361cabc486a2f3567d646363334d50cc462"
},
{
"name" : "spirv-tools/external/spirv-headers",
"site" : "github",
"subrepo" : "KhronosGroup/SPIRV-Headers",
"subdir" : "External/spirv-tools/external/spirv-headers",
"commit" : "79b6681aadcb53c27d1052e5f8a0e82a981dbf2f"
"commit" : "e74c389f81915d0a48d6df1af83c3862c5ad85ab"
}
]
}