SPV: Implement Vulkan 1.1 features and extensions.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
old mode 100755
new mode 100644
index 21cd869..45e76ad
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -1,6 +1,7 @@
//
// Copyright (C) 2014-2016 LunarG, Inc.
// Copyright (C) 2015-2016 Google, Inc.
+// Copyright (C) 2017 ARM Limited.
//
// All rights reserved.
//
@@ -172,10 +173,12 @@
spv::Id createUnaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
spv::Id createUnaryMatrixOperation(spv::Op op, spv::Decoration precision, spv::Decoration noContraction, spv::Id typeId, spv::Id operand,glslang::TBasicType typeProxy);
spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy);
+ spv::Id createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize);
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands);
+ spv::Id createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
@@ -191,6 +194,11 @@
#ifdef AMD_EXTENSIONS
spv::Id getExtBuiltins(const char* name);
#endif
+ void addPre13Extension(const char* ext)
+ {
+ if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+ builder.addExtension(ext);
+ }
glslang::SpvOptions& options;
spv::Function* shaderEntry;
@@ -504,17 +512,17 @@
case glslang::EbvInstanceIndex: return spv::BuiltInInstanceIndex;
case glslang::EbvBaseVertex:
- builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+ addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseVertex;
case glslang::EbvBaseInstance:
- builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+ addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInBaseInstance;
case glslang::EbvDrawId:
- builder.addExtension(spv::E_SPV_KHR_shader_draw_parameters);
+ addPre13Extension(spv::E_SPV_KHR_shader_draw_parameters);
builder.addCapability(spv::CapabilityDrawParameters);
return spv::BuiltInDrawIndex;
@@ -580,6 +588,46 @@
builder.addCapability(spv::CapabilitySubgroupBallotKHR);
return spv::BuiltInSubgroupLtMaskKHR;
+ case glslang::EbvNumSubgroups:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ return spv::BuiltInNumSubgroups;
+
+ case glslang::EbvSubgroupID:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ return spv::BuiltInSubgroupId;
+
+ case glslang::EbvSubgroupSize2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ return spv::BuiltInSubgroupSize;
+
+ case glslang::EbvSubgroupInvocation2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ return spv::BuiltInSubgroupLocalInvocationId;
+
+ case glslang::EbvSubgroupEqMask2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ return spv::BuiltInSubgroupEqMask;
+
+ case glslang::EbvSubgroupGeMask2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ return spv::BuiltInSubgroupGeMask;
+
+ case glslang::EbvSubgroupGtMask2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ return spv::BuiltInSubgroupGtMask;
+
+ case glslang::EbvSubgroupLeMask2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ return spv::BuiltInSubgroupLeMask;
+
+ case glslang::EbvSubgroupLtMask2:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ return spv::BuiltInSubgroupLtMask;
#ifdef AMD_EXTENSIONS
case glslang::EbvBaryCoordNoPersp:
builder.addExtension(spv::E_SPV_AMD_shader_explicit_vertex_parameter);
@@ -611,12 +659,12 @@
#endif
case glslang::EbvDeviceIndex:
- builder.addExtension(spv::E_SPV_KHR_device_group);
+ addPre13Extension(spv::E_SPV_KHR_device_group);
builder.addCapability(spv::CapabilityDeviceGroup);
return spv::BuiltInDeviceIndex;
case glslang::EbvViewIndex:
- builder.addExtension(spv::E_SPV_KHR_multiview);
+ addPre13Extension(spv::E_SPV_KHR_multiview);
builder.addCapability(spv::CapabilityMultiView);
return spv::BuiltInViewIndex;
@@ -804,7 +852,7 @@
}
if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) {
- builder.addExtension(spv::E_SPV_KHR_storage_buffer_storage_class);
+ addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class);
return spv::StorageClassStorageBuffer;
}
@@ -1436,16 +1484,14 @@
one = builder.makeFloatConstant(1.0F);
else if (node->getBasicType() == glslang::EbtDouble)
one = builder.makeDoubleConstant(1.0);
-#ifdef AMD_EXTENSIONS
else if (node->getBasicType() == glslang::EbtFloat16)
one = builder.makeFloat16Constant(1.0F);
-#endif
- else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
- one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
+ else if (node->getBasicType() == glslang::EbtInt8 || node->getBasicType() == glslang::EbtUint8)
+ one = builder.makeInt8Constant(1);
else if (node->getBasicType() == glslang::EbtInt16 || node->getBasicType() == glslang::EbtUint16)
one = builder.makeInt16Constant(1);
-#endif
+ else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
+ one = builder.makeInt64Constant(1);
else
one = builder.makeIntConstant(1);
glslang::TOperator op;
@@ -1650,7 +1696,6 @@
case glslang::EOpConstructBMat4x2:
case glslang::EOpConstructBMat4x3:
case glslang::EOpConstructBMat4x4:
-#ifdef AMD_EXTENSIONS
case glslang::EOpConstructF16Mat2x2:
case glslang::EOpConstructF16Mat2x3:
case glslang::EOpConstructF16Mat2x4:
@@ -1660,7 +1705,6 @@
case glslang::EOpConstructF16Mat4x2:
case glslang::EOpConstructF16Mat4x3:
case glslang::EOpConstructF16Mat4x4:
-#endif
isMatrix = true;
// fall through
case glslang::EOpConstructFloat:
@@ -1671,16 +1715,30 @@
case glslang::EOpConstructDVec2:
case glslang::EOpConstructDVec3:
case glslang::EOpConstructDVec4:
-#ifdef AMD_EXTENSIONS
case glslang::EOpConstructFloat16:
case glslang::EOpConstructF16Vec2:
case glslang::EOpConstructF16Vec3:
case glslang::EOpConstructF16Vec4:
-#endif
case glslang::EOpConstructBool:
case glslang::EOpConstructBVec2:
case glslang::EOpConstructBVec3:
case glslang::EOpConstructBVec4:
+ case glslang::EOpConstructInt8:
+ case glslang::EOpConstructI8Vec2:
+ case glslang::EOpConstructI8Vec3:
+ case glslang::EOpConstructI8Vec4:
+ case glslang::EOpConstructUint8:
+ case glslang::EOpConstructU8Vec2:
+ case glslang::EOpConstructU8Vec3:
+ case glslang::EOpConstructU8Vec4:
+ case glslang::EOpConstructInt16:
+ case glslang::EOpConstructI16Vec2:
+ case glslang::EOpConstructI16Vec3:
+ case glslang::EOpConstructI16Vec4:
+ case glslang::EOpConstructUint16:
+ case glslang::EOpConstructU16Vec2:
+ case glslang::EOpConstructU16Vec3:
+ case glslang::EOpConstructU16Vec4:
case glslang::EOpConstructInt:
case glslang::EOpConstructIVec2:
case glslang::EOpConstructIVec3:
@@ -1697,16 +1755,6 @@
case glslang::EOpConstructU64Vec2:
case glslang::EOpConstructU64Vec3:
case glslang::EOpConstructU64Vec4:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConstructInt16:
- case glslang::EOpConstructI16Vec2:
- case glslang::EOpConstructI16Vec3:
- case glslang::EOpConstructI16Vec4:
- case glslang::EOpConstructUint16:
- case glslang::EOpConstructU16Vec2:
- case glslang::EOpConstructU16Vec3:
- case glslang::EOpConstructU16Vec4:
-#endif
case glslang::EOpConstructStruct:
case glslang::EOpConstructTextureSampler:
{
@@ -1787,6 +1835,11 @@
case glslang::EOpDeviceMemoryBarrierWithGroupSync:
case glslang::EOpWorkgroupMemoryBarrier:
case glslang::EOpWorkgroupMemoryBarrierWithGroupSync:
+ case glslang::EOpSubgroupBarrier:
+ case glslang::EOpSubgroupMemoryBarrier:
+ case glslang::EOpSubgroupMemoryBarrierBuffer:
+ case glslang::EOpSubgroupMemoryBarrierImage:
+ case glslang::EOpSubgroupMemoryBarrierShared:
noReturnValue = true;
// These all have 0 operands and will naturally finish up in the code below for 0 operands
break;
@@ -2308,25 +2361,23 @@
spv::StorageClass storageClass = TranslateStorageClass(node->getType());
spv::Id spvType = convertGlslangToSpvType(node->getType());
-#ifdef AMD_EXTENSIONS
const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) ||
node->getType().containsBasicType(glslang::EbtInt16) ||
node->getType().containsBasicType(glslang::EbtUint16);
if (contains16BitType) {
if (storageClass == spv::StorageClassInput || storageClass == spv::StorageClassOutput) {
- builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+ addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStorageInputOutput16);
} else if (storageClass == spv::StorageClassPushConstant) {
- builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+ addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStoragePushConstant16);
} else if (storageClass == spv::StorageClassUniform) {
- builder.addExtension(spv::E_SPV_KHR_16bit_storage);
+ addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStorageUniform16);
if (node->getType().getQualifier().storage == glslang::EvqBuffer)
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
}
}
-#endif
const char* name = node->getName().c_str();
if (glslang::IsAnonymous(name))
@@ -2409,12 +2460,14 @@
case glslang::EbtDouble:
spvType = builder.makeFloatType(64);
break;
-#ifdef AMD_EXTENSIONS
case glslang::EbtFloat16:
- builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+ builder.addCapability(spv::CapabilityFloat16);
+#if AMD_EXTENSIONS
+ if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+ builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
+#endif
spvType = builder.makeFloatType(16);
break;
-#endif
case glslang::EbtBool:
// "transparent" bool doesn't exist in SPIR-V. The GLSL convention is
// a 32-bit int where non-0 means true.
@@ -2423,6 +2476,30 @@
else
spvType = builder.makeBoolType();
break;
+ case glslang::EbtInt8:
+ builder.addCapability(spv::CapabilityInt8);
+ spvType = builder.makeIntType(8);
+ break;
+ case glslang::EbtUint8:
+ builder.addCapability(spv::CapabilityInt8);
+ spvType = builder.makeUintType(8);
+ break;
+ case glslang::EbtInt16:
+ builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+ if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+ builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+ spvType = builder.makeIntType(16);
+ break;
+ case glslang::EbtUint16:
+ builder.addCapability(spv::CapabilityInt16);
+#ifdef AMD_EXTENSIONS
+ if (builder.getSpvVersion() < glslang::EShTargetSpv_1_3)
+ builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
+#endif
+ spvType = builder.makeUintType(16);
+ break;
case glslang::EbtInt:
spvType = builder.makeIntType(32);
break;
@@ -2435,16 +2512,6 @@
case glslang::EbtUint64:
spvType = builder.makeUintType(64);
break;
-#ifdef AMD_EXTENSIONS
- case glslang::EbtInt16:
- builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
- spvType = builder.makeIntType(16);
- break;
- case glslang::EbtUint16:
- builder.addExtension(spv::E_SPV_AMD_gpu_shader_int16);
- spvType = builder.makeUintType(16);
- break;
-#endif
case glslang::EbtAtomicUint:
builder.addCapability(spv::CapabilityAtomicStorage);
spvType = builder.makeUintType(32);
@@ -3830,13 +3897,8 @@
spv::Id typeId, spv::Id left, spv::Id right,
glslang::TBasicType typeProxy, bool reduceComparison)
{
-#ifdef AMD_EXTENSIONS
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+ bool isUnsigned = isTypeUnsignedInt(typeProxy);
+ bool isFloat = isTypeFloat(typeProxy);
bool isBool = typeProxy == glslang::EbtBool;
spv::Op binOp = spv::OpNop;
@@ -4161,13 +4223,8 @@
spv::Op unaryOp = spv::OpNop;
int extBuiltins = -1;
int libCall = -1;
-#ifdef AMD_EXTENSIONS
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+ bool isUnsigned = isTypeUnsignedInt(typeProxy);
+ bool isFloat = isTypeFloat(typeProxy);
switch (op) {
case glslang::EOpNegative:
@@ -4304,12 +4361,10 @@
case glslang::EOpDoubleBitsToUint64:
case glslang::EOpInt64BitsToDouble:
case glslang::EOpUint64BitsToDouble:
-#ifdef AMD_EXTENSIONS
case glslang::EOpFloat16BitsToInt16:
case glslang::EOpFloat16BitsToUint16:
case glslang::EOpInt16BitsToFloat16:
case glslang::EOpUint16BitsToFloat16:
-#endif
unaryOp = spv::OpBitcast;
break;
@@ -4354,10 +4409,12 @@
case glslang::EOpUnpackInt2x32:
case glslang::EOpPackUint2x32:
case glslang::EOpUnpackUint2x32:
- unaryOp = spv::OpBitcast;
- break;
-
-#ifdef AMD_EXTENSIONS
+ case glslang::EOpPack16:
+ case glslang::EOpPack32:
+ case glslang::EOpPack64:
+ case glslang::EOpUnpack32:
+ case glslang::EOpUnpack16:
+ case glslang::EOpUnpack8:
case glslang::EOpPackInt2x16:
case glslang::EOpUnpackInt2x16:
case glslang::EOpPackUint2x16:
@@ -4370,7 +4427,6 @@
case glslang::EOpUnpackFloat2x16:
unaryOp = spv::OpBitcast;
break;
-#endif
case glslang::EOpDPdx:
unaryOp = spv::OpDPdx;
@@ -4485,7 +4541,45 @@
operands.push_back(operand);
return createInvocationsOperation(op, typeId, operands, typeProxy);
}
-
+ case glslang::EOpSubgroupAll:
+ case glslang::EOpSubgroupAny:
+ case glslang::EOpSubgroupAllEqual:
+ case glslang::EOpSubgroupBroadcastFirst:
+ case glslang::EOpSubgroupBallot:
+ case glslang::EOpSubgroupInverseBallot:
+ case glslang::EOpSubgroupBallotBitCount:
+ case glslang::EOpSubgroupBallotInclusiveBitCount:
+ case glslang::EOpSubgroupBallotExclusiveBitCount:
+ case glslang::EOpSubgroupBallotFindLSB:
+ case glslang::EOpSubgroupBallotFindMSB:
+ case glslang::EOpSubgroupAdd:
+ case glslang::EOpSubgroupMul:
+ case glslang::EOpSubgroupMin:
+ case glslang::EOpSubgroupMax:
+ case glslang::EOpSubgroupAnd:
+ case glslang::EOpSubgroupOr:
+ case glslang::EOpSubgroupXor:
+ case glslang::EOpSubgroupInclusiveAdd:
+ case glslang::EOpSubgroupInclusiveMul:
+ case glslang::EOpSubgroupInclusiveMin:
+ case glslang::EOpSubgroupInclusiveMax:
+ case glslang::EOpSubgroupInclusiveAnd:
+ case glslang::EOpSubgroupInclusiveOr:
+ case glslang::EOpSubgroupInclusiveXor:
+ case glslang::EOpSubgroupExclusiveAdd:
+ case glslang::EOpSubgroupExclusiveMul:
+ case glslang::EOpSubgroupExclusiveMin:
+ case glslang::EOpSubgroupExclusiveMax:
+ case glslang::EOpSubgroupExclusiveAnd:
+ case glslang::EOpSubgroupExclusiveOr:
+ case glslang::EOpSubgroupExclusiveXor:
+ case glslang::EOpSubgroupQuadSwapHorizontal:
+ case glslang::EOpSubgroupQuadSwapVertical:
+ case glslang::EOpSubgroupQuadSwapDiagonal: {
+ std::vector<spv::Id> operands;
+ operands.push_back(operand);
+ return createSubgroupOperation(op, typeId, operands, typeProxy);
+ }
#ifdef AMD_EXTENSIONS
case glslang::EOpMbcnt:
extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -4551,32 +4645,150 @@
return builder.setPrecision(builder.createCompositeConstruct(typeId, results), precision);
}
+spv::Id TGlslangToSpvTraverser::createConversionOperation(glslang::TOperator op, spv::Id operand, int vectorSize)
+{
+ spv::Op convOp = spv::OpNop;
+ spv::Id type = 0;
+
+ spv::Id result = 0;
+
+ switch(op) {
+ case glslang::EOpConvInt8ToUint16:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvInt8ToUint:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(32);
+ break;
+ case glslang::EOpConvInt8ToUint64:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvInt16ToUint8:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvInt16ToUint:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(32);
+ break;
+ case glslang::EOpConvInt16ToUint64:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvIntToUint8:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvIntToUint16:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvIntToUint64:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvInt64ToUint8:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvInt64ToUint16:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvInt64ToUint:
+ convOp = spv::OpSConvert;
+ type = builder.makeIntType(32);
+ break;
+ case glslang::EOpConvUint8ToInt16:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvUint8ToInt:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(32);
+ break;
+ case glslang::EOpConvUint8ToInt64:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvUint16ToInt8:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvUint16ToInt:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(32);
+ break;
+ case glslang::EOpConvUint16ToInt64:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvUintToInt8:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvUintToInt16:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvUintToInt64:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(64);
+ break;
+ case glslang::EOpConvUint64ToInt8:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(8);
+ break;
+ case glslang::EOpConvUint64ToInt16:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(16);
+ break;
+ case glslang::EOpConvUint64ToInt:
+ convOp = spv::OpUConvert;
+ type = builder.makeIntType(32);
+ break;
+
+ default:
+ assert(false && "Default missing");
+ break;
+ }
+
+ if (vectorSize > 0)
+ type = builder.makeVectorType(type, vectorSize);
+
+ result = builder.createUnaryOp(convOp, type, operand);
+ return result;
+}
+
spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, spv::Decoration precision, spv::Decoration noContraction, spv::Id destType, spv::Id operand, glslang::TBasicType typeProxy)
{
spv::Op convOp = spv::OpNop;
spv::Id zero = 0;
spv::Id one = 0;
- spv::Id type = 0;
int vectorSize = builder.isVectorType(destType) ? builder.getNumTypeComponents(destType) : 0;
switch (op) {
- case glslang::EOpConvIntToBool:
- case glslang::EOpConvUintToBool:
- case glslang::EOpConvInt64ToBool:
- case glslang::EOpConvUint64ToBool:
-#ifdef AMD_EXTENSIONS
+ case glslang::EOpConvInt8ToBool:
+ case glslang::EOpConvUint8ToBool:
+ zero = builder.makeUint8Constant(0);
+ zero = makeSmearedConstant(zero, vectorSize);
+ return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
case glslang::EOpConvInt16ToBool:
case glslang::EOpConvUint16ToBool:
-#endif
- if (op == glslang::EOpConvInt64ToBool || op == glslang::EOpConvUint64ToBool)
- zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvInt16ToBool || op == glslang::EOpConvUint16ToBool)
- zero = builder.makeUint16Constant(0);
-#endif
- else
- zero = builder.makeUintConstant(0);
+ zero = builder.makeUint16Constant(0);
+ zero = makeSmearedConstant(zero, vectorSize);
+ return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+ case glslang::EOpConvIntToBool:
+ case glslang::EOpConvUintToBool:
+ zero = builder.makeUintConstant(0);
+ zero = makeSmearedConstant(zero, vectorSize);
+ return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
+ case glslang::EOpConvInt64ToBool:
+ case glslang::EOpConvUint64ToBool:
+ zero = builder.makeUint64Constant(0);
zero = makeSmearedConstant(zero, vectorSize);
return builder.createBinOp(spv::OpINotEqual, destType, operand, zero);
@@ -4590,12 +4802,10 @@
zero = makeSmearedConstant(zero, vectorSize);
return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-#ifdef AMD_EXTENSIONS
case glslang::EOpConvFloat16ToBool:
zero = builder.makeFloat16Constant(0.0F);
zero = makeSmearedConstant(zero, vectorSize);
return builder.createBinOp(spv::OpFOrdNotEqual, destType, operand, zero);
-#endif
case glslang::EOpConvBoolToFloat:
convOp = spv::OpSelect;
@@ -4609,34 +4819,45 @@
one = builder.makeDoubleConstant(1.0);
break;
-#ifdef AMD_EXTENSIONS
case glslang::EOpConvBoolToFloat16:
convOp = spv::OpSelect;
zero = builder.makeFloat16Constant(0.0F);
one = builder.makeFloat16Constant(1.0F);
break;
-#endif
+
+ case glslang::EOpConvBoolToInt8:
+ zero = builder.makeInt8Constant(0);
+ one = builder.makeInt8Constant(1);
+ convOp = spv::OpSelect;
+ break;
+
+ case glslang::EOpConvBoolToUint8:
+ zero = builder.makeUint8Constant(0);
+ one = builder.makeUint8Constant(1);
+ convOp = spv::OpSelect;
+ break;
+
+ case glslang::EOpConvBoolToInt16:
+ zero = builder.makeInt16Constant(0);
+ one = builder.makeInt16Constant(1);
+ convOp = spv::OpSelect;
+ break;
+
+ case glslang::EOpConvBoolToUint16:
+ zero = builder.makeUint16Constant(0);
+ one = builder.makeUint16Constant(1);
+ convOp = spv::OpSelect;
+ break;
case glslang::EOpConvBoolToInt:
case glslang::EOpConvBoolToInt64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvBoolToInt16:
-#endif
if (op == glslang::EOpConvBoolToInt64)
zero = builder.makeInt64Constant(0);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvBoolToInt16)
- zero = builder.makeInt16Constant(0);
-#endif
else
zero = builder.makeIntConstant(0);
if (op == glslang::EOpConvBoolToInt64)
one = builder.makeInt64Constant(1);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvBoolToInt16)
- one = builder.makeInt16Constant(1);
-#endif
else
one = builder.makeIntConstant(1);
@@ -4645,104 +4866,94 @@
case glslang::EOpConvBoolToUint:
case glslang::EOpConvBoolToUint64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvBoolToUint16:
-#endif
if (op == glslang::EOpConvBoolToUint64)
zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvBoolToUint16)
- zero = builder.makeUint16Constant(0);
-#endif
else
zero = builder.makeUintConstant(0);
if (op == glslang::EOpConvBoolToUint64)
one = builder.makeUint64Constant(1);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvBoolToUint16)
- one = builder.makeUint16Constant(1);
-#endif
else
one = builder.makeUintConstant(1);
convOp = spv::OpSelect;
break;
+ case glslang::EOpConvInt8ToFloat16:
+ case glslang::EOpConvInt8ToFloat:
+ case glslang::EOpConvInt8ToDouble:
+ case glslang::EOpConvInt16ToFloat16:
+ case glslang::EOpConvInt16ToFloat:
+ case glslang::EOpConvInt16ToDouble:
+ case glslang::EOpConvIntToFloat16:
case glslang::EOpConvIntToFloat:
case glslang::EOpConvIntToDouble:
case glslang::EOpConvInt64ToFloat:
case glslang::EOpConvInt64ToDouble:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvInt16ToFloat:
- case glslang::EOpConvInt16ToDouble:
- case glslang::EOpConvInt16ToFloat16:
- case glslang::EOpConvIntToFloat16:
case glslang::EOpConvInt64ToFloat16:
-#endif
convOp = spv::OpConvertSToF;
break;
+ case glslang::EOpConvUint8ToFloat16:
+ case glslang::EOpConvUint8ToFloat:
+ case glslang::EOpConvUint8ToDouble:
+ case glslang::EOpConvUint16ToFloat16:
+ case glslang::EOpConvUint16ToFloat:
+ case glslang::EOpConvUint16ToDouble:
+ case glslang::EOpConvUintToFloat16:
case glslang::EOpConvUintToFloat:
case glslang::EOpConvUintToDouble:
case glslang::EOpConvUint64ToFloat:
case glslang::EOpConvUint64ToDouble:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUint16ToFloat:
- case glslang::EOpConvUint16ToDouble:
- case glslang::EOpConvUint16ToFloat16:
- case glslang::EOpConvUintToFloat16:
case glslang::EOpConvUint64ToFloat16:
-#endif
convOp = spv::OpConvertUToF;
break;
case glslang::EOpConvDoubleToFloat:
case glslang::EOpConvFloatToDouble:
-#ifdef AMD_EXTENSIONS
case glslang::EOpConvDoubleToFloat16:
case glslang::EOpConvFloat16ToDouble:
case glslang::EOpConvFloatToFloat16:
case glslang::EOpConvFloat16ToFloat:
-#endif
convOp = spv::OpFConvert;
if (builder.isMatrixType(destType))
return createUnaryMatrixOperation(convOp, precision, noContraction, destType, operand, typeProxy);
break;
- case glslang::EOpConvFloatToInt:
- case glslang::EOpConvDoubleToInt:
- case glslang::EOpConvFloatToInt64:
- case glslang::EOpConvDoubleToInt64:
-#ifdef AMD_EXTENSIONS
+ case glslang::EOpConvFloat16ToInt8:
+ case glslang::EOpConvFloatToInt8:
+ case glslang::EOpConvDoubleToInt8:
+ case glslang::EOpConvFloat16ToInt16:
case glslang::EOpConvFloatToInt16:
case glslang::EOpConvDoubleToInt16:
- case glslang::EOpConvFloat16ToInt16:
case glslang::EOpConvFloat16ToInt:
+ case glslang::EOpConvFloatToInt:
+ case glslang::EOpConvDoubleToInt:
case glslang::EOpConvFloat16ToInt64:
-#endif
+ case glslang::EOpConvFloatToInt64:
+ case glslang::EOpConvDoubleToInt64:
convOp = spv::OpConvertFToS;
break;
+ case glslang::EOpConvUint8ToInt8:
+ case glslang::EOpConvInt8ToUint8:
+ case glslang::EOpConvUint16ToInt16:
+ case glslang::EOpConvInt16ToUint16:
case glslang::EOpConvUintToInt:
case glslang::EOpConvIntToUint:
case glslang::EOpConvUint64ToInt64:
case glslang::EOpConvInt64ToUint64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUint16ToInt16:
- case glslang::EOpConvInt16ToUint16:
-#endif
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd.
- if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64)
- zero = builder.makeUint64Constant(0);
-#ifdef AMD_EXTENSIONS
- else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16)
+ if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) {
+ zero = builder.makeUint8Constant(0);
+ } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) {
zero = builder.makeUint16Constant(0);
-#endif
- else
+ } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) {
+ zero = builder.makeUint64Constant(0);
+ } else {
zero = builder.makeUintConstant(0);
-
+ }
zero = makeSmearedConstant(zero, vectorSize);
// Use OpIAdd, instead of OpBitcast to do the conversion when
// generating for OpSpecConstantOp instruction.
@@ -4752,126 +4963,117 @@
convOp = spv::OpBitcast;
break;
+ case glslang::EOpConvFloat16ToUint8:
+ case glslang::EOpConvFloatToUint8:
+ case glslang::EOpConvDoubleToUint8:
+ case glslang::EOpConvFloat16ToUint16:
+ case glslang::EOpConvFloatToUint16:
+ case glslang::EOpConvDoubleToUint16:
+ case glslang::EOpConvFloat16ToUint:
case glslang::EOpConvFloatToUint:
case glslang::EOpConvDoubleToUint:
case glslang::EOpConvFloatToUint64:
case glslang::EOpConvDoubleToUint64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvFloatToUint16:
- case glslang::EOpConvDoubleToUint16:
- case glslang::EOpConvFloat16ToUint16:
- case glslang::EOpConvFloat16ToUint:
case glslang::EOpConvFloat16ToUint64:
-#endif
convOp = spv::OpConvertFToU;
break;
- case glslang::EOpConvIntToInt64:
- case glslang::EOpConvInt64ToInt:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvIntToInt16:
+ case glslang::EOpConvInt8ToInt16:
+ case glslang::EOpConvInt8ToInt:
+ case glslang::EOpConvInt8ToInt64:
+ case glslang::EOpConvInt16ToInt8:
case glslang::EOpConvInt16ToInt:
- case glslang::EOpConvInt64ToInt16:
case glslang::EOpConvInt16ToInt64:
-#endif
+ case glslang::EOpConvIntToInt8:
+ case glslang::EOpConvIntToInt16:
+ case glslang::EOpConvIntToInt64:
+ case glslang::EOpConvInt64ToInt8:
+ case glslang::EOpConvInt64ToInt16:
+ case glslang::EOpConvInt64ToInt:
convOp = spv::OpSConvert;
break;
- case glslang::EOpConvUintToUint64:
- case glslang::EOpConvUint64ToUint:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUintToUint16:
+ case glslang::EOpConvUint8ToUint16:
+ case glslang::EOpConvUint8ToUint:
+ case glslang::EOpConvUint8ToUint64:
+ case glslang::EOpConvUint16ToUint8:
case glslang::EOpConvUint16ToUint:
- case glslang::EOpConvUint64ToUint16:
case glslang::EOpConvUint16ToUint64:
-#endif
+ case glslang::EOpConvUintToUint8:
+ case glslang::EOpConvUintToUint16:
+ case glslang::EOpConvUintToUint64:
+ case glslang::EOpConvUint64ToUint8:
+ case glslang::EOpConvUint64ToUint16:
+ case glslang::EOpConvUint64ToUint:
convOp = spv::OpUConvert;
break;
- case glslang::EOpConvIntToUint64:
- case glslang::EOpConvInt64ToUint:
- case glslang::EOpConvUint64ToInt:
- case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
+ case glslang::EOpConvInt8ToUint16:
+ case glslang::EOpConvInt8ToUint:
+ case glslang::EOpConvInt8ToUint64:
+ case glslang::EOpConvInt16ToUint8:
case glslang::EOpConvInt16ToUint:
- case glslang::EOpConvUintToInt16:
case glslang::EOpConvInt16ToUint64:
- case glslang::EOpConvUint64ToInt16:
- case glslang::EOpConvUint16ToInt:
+ case glslang::EOpConvIntToUint8:
case glslang::EOpConvIntToUint16:
- case glslang::EOpConvUint16ToInt64:
+ case glslang::EOpConvIntToUint64:
+ case glslang::EOpConvInt64ToUint8:
case glslang::EOpConvInt64ToUint16:
-#endif
+ case glslang::EOpConvInt64ToUint:
+ case glslang::EOpConvUint8ToInt16:
+ case glslang::EOpConvUint8ToInt:
+ case glslang::EOpConvUint8ToInt64:
+ case glslang::EOpConvUint16ToInt8:
+ case glslang::EOpConvUint16ToInt:
+ case glslang::EOpConvUint16ToInt64:
+ case glslang::EOpConvUintToInt8:
+ case glslang::EOpConvUintToInt16:
+ case glslang::EOpConvUintToInt64:
+ case glslang::EOpConvUint64ToInt8:
+ case glslang::EOpConvUint64ToInt16:
+ case glslang::EOpConvUint64ToInt:
// OpSConvert/OpUConvert + OpBitCast
- switch (op) {
- case glslang::EOpConvIntToUint64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvInt16ToUint64:
-#endif
- convOp = spv::OpSConvert;
- type = builder.makeIntType(64);
- break;
- case glslang::EOpConvInt64ToUint:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvInt16ToUint:
-#endif
- convOp = spv::OpSConvert;
- type = builder.makeIntType(32);
- break;
- case glslang::EOpConvUint64ToInt:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUint16ToInt:
-#endif
- convOp = spv::OpUConvert;
- type = builder.makeUintType(32);
- break;
- case glslang::EOpConvUintToInt64:
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUint16ToInt64:
-#endif
- convOp = spv::OpUConvert;
- type = builder.makeUintType(64);
- break;
-#ifdef AMD_EXTENSIONS
- case glslang::EOpConvUintToInt16:
- case glslang::EOpConvUint64ToInt16:
- convOp = spv::OpUConvert;
- type = builder.makeUintType(16);
- break;
- case glslang::EOpConvIntToUint16:
- case glslang::EOpConvInt64ToUint16:
- convOp = spv::OpSConvert;
- type = builder.makeIntType(16);
- break;
-#endif
- default:
- assert(0);
- break;
- }
-
- if (vectorSize > 0)
- type = builder.makeVectorType(type, vectorSize);
-
- operand = builder.createUnaryOp(convOp, type, operand);
+ operand = createConversionOperation(op, operand, vectorSize);
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd.
-#ifdef AMD_EXTENSIONS
- if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64 ||
- op == glslang::EOpConvInt16ToUint64 || op == glslang::EOpConvUint16ToInt64)
- zero = builder.makeUint64Constant(0);
- else if (op == glslang::EOpConvIntToUint16 || op == glslang::EOpConvUintToInt16 ||
- op == glslang::EOpConvInt64ToUint16 || op == glslang::EOpConvUint64ToInt16)
+ switch(op) {
+ case glslang::EOpConvInt16ToUint8:
+ case glslang::EOpConvIntToUint8:
+ case glslang::EOpConvInt64ToUint8:
+ case glslang::EOpConvUint16ToInt8:
+ case glslang::EOpConvUintToInt8:
+ case glslang::EOpConvUint64ToInt8:
+ zero = builder.makeUint8Constant(0);
+ break;
+ case glslang::EOpConvInt8ToUint16:
+ case glslang::EOpConvIntToUint16:
+ case glslang::EOpConvInt64ToUint16:
+ case glslang::EOpConvUint8ToInt16:
+ case glslang::EOpConvUintToInt16:
+ case glslang::EOpConvUint64ToInt16:
zero = builder.makeUint16Constant(0);
- else
+ break;
+ case glslang::EOpConvInt8ToUint:
+ case glslang::EOpConvInt16ToUint:
+ case glslang::EOpConvInt64ToUint:
+ case glslang::EOpConvUint8ToInt:
+ case glslang::EOpConvUint16ToInt:
+ case glslang::EOpConvUint64ToInt:
zero = builder.makeUintConstant(0);
-#else
- if (op == glslang::EOpConvIntToUint64 || op == glslang::EOpConvUintToInt64)
+ break;
+ case glslang::EOpConvInt8ToUint64:
+ case glslang::EOpConvInt16ToUint64:
+ case glslang::EOpConvIntToUint64:
+ case glslang::EOpConvUint8ToInt64:
+ case glslang::EOpConvUint16ToInt64:
+ case glslang::EOpConvUintToInt64:
zero = builder.makeUint64Constant(0);
- else
- zero = builder.makeUintConstant(0);
-#endif
-
+ break;
+ default:
+ assert(false && "Default missing");
+ break;
+ }
zero = makeSmearedConstant(zero, vectorSize);
// Use OpIAdd, instead of OpBitcast to do the conversion when
// generating for OpSpecConstantOp instruction.
@@ -5013,10 +5215,8 @@
// Create group invocation operations.
spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
-#ifdef AMD_EXTENSIONS
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#endif
+ bool isUnsigned = isTypeUnsignedInt(typeProxy);
+ bool isFloat = isTypeFloat(typeProxy);
spv::Op opCode = spv::OpNop;
std::vector<spv::Id> spvGroupOperands;
@@ -5277,15 +5477,263 @@
return builder.createCompositeConstruct(typeId, results);
}
+// Create subgroup invocation operations.
+spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+{
+ // Add the required capabilities.
+ switch (op) {
+ case glslang::EOpSubgroupElect:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ break;
+ case glslang::EOpSubgroupAll:
+ case glslang::EOpSubgroupAny:
+ case glslang::EOpSubgroupAllEqual:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformVote);
+ break;
+ case glslang::EOpSubgroupBroadcast:
+ case glslang::EOpSubgroupBroadcastFirst:
+ case glslang::EOpSubgroupBallot:
+ case glslang::EOpSubgroupInverseBallot:
+ case glslang::EOpSubgroupBallotBitExtract:
+ case glslang::EOpSubgroupBallotBitCount:
+ case glslang::EOpSubgroupBallotInclusiveBitCount:
+ case glslang::EOpSubgroupBallotExclusiveBitCount:
+ case glslang::EOpSubgroupBallotFindLSB:
+ case glslang::EOpSubgroupBallotFindMSB:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformBallot);
+ break;
+ case glslang::EOpSubgroupShuffle:
+ case glslang::EOpSubgroupShuffleXor:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformShuffle);
+ break;
+ case glslang::EOpSubgroupShuffleUp:
+ case glslang::EOpSubgroupShuffleDown:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformShuffleRelative);
+ break;
+ case glslang::EOpSubgroupAdd:
+ case glslang::EOpSubgroupMul:
+ case glslang::EOpSubgroupMin:
+ case glslang::EOpSubgroupMax:
+ case glslang::EOpSubgroupAnd:
+ case glslang::EOpSubgroupOr:
+ case glslang::EOpSubgroupXor:
+ case glslang::EOpSubgroupInclusiveAdd:
+ case glslang::EOpSubgroupInclusiveMul:
+ case glslang::EOpSubgroupInclusiveMin:
+ case glslang::EOpSubgroupInclusiveMax:
+ case glslang::EOpSubgroupInclusiveAnd:
+ case glslang::EOpSubgroupInclusiveOr:
+ case glslang::EOpSubgroupInclusiveXor:
+ case glslang::EOpSubgroupExclusiveAdd:
+ case glslang::EOpSubgroupExclusiveMul:
+ case glslang::EOpSubgroupExclusiveMin:
+ case glslang::EOpSubgroupExclusiveMax:
+ case glslang::EOpSubgroupExclusiveAnd:
+ case glslang::EOpSubgroupExclusiveOr:
+ case glslang::EOpSubgroupExclusiveXor:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformArithmetic);
+ break;
+ case glslang::EOpSubgroupClusteredAdd:
+ case glslang::EOpSubgroupClusteredMul:
+ case glslang::EOpSubgroupClusteredMin:
+ case glslang::EOpSubgroupClusteredMax:
+ case glslang::EOpSubgroupClusteredAnd:
+ case glslang::EOpSubgroupClusteredOr:
+ case glslang::EOpSubgroupClusteredXor:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformClustered);
+ break;
+ case glslang::EOpSubgroupQuadBroadcast:
+ case glslang::EOpSubgroupQuadSwapHorizontal:
+ case glslang::EOpSubgroupQuadSwapVertical:
+ case glslang::EOpSubgroupQuadSwapDiagonal:
+ builder.addCapability(spv::CapabilityGroupNonUniform);
+ builder.addCapability(spv::CapabilityGroupNonUniformQuad);
+ break;
+ default: assert(0 && "Unhandled subgroup operation!");
+ }
+
+ const bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
+ const bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
+ const bool isBool = typeProxy == glslang::EbtBool;
+
+ spv::Op opCode = spv::OpNop;
+
+ // Figure out which opcode to use.
+ switch (op) {
+ case glslang::EOpSubgroupElect: opCode = spv::OpGroupNonUniformElect; break;
+ case glslang::EOpSubgroupAll: opCode = spv::OpGroupNonUniformAll; break;
+ case glslang::EOpSubgroupAny: opCode = spv::OpGroupNonUniformAny; break;
+ case glslang::EOpSubgroupAllEqual: opCode = spv::OpGroupNonUniformAllEqual; break;
+ case glslang::EOpSubgroupBroadcast: opCode = spv::OpGroupNonUniformBroadcast; break;
+ case glslang::EOpSubgroupBroadcastFirst: opCode = spv::OpGroupNonUniformBroadcastFirst; break;
+ case glslang::EOpSubgroupBallot: opCode = spv::OpGroupNonUniformBallot; break;
+ case glslang::EOpSubgroupInverseBallot: opCode = spv::OpGroupNonUniformInverseBallot; break;
+ case glslang::EOpSubgroupBallotBitExtract: opCode = spv::OpGroupNonUniformBallotBitExtract; break;
+ case glslang::EOpSubgroupBallotBitCount:
+ case glslang::EOpSubgroupBallotInclusiveBitCount:
+ case glslang::EOpSubgroupBallotExclusiveBitCount: opCode = spv::OpGroupNonUniformBallotBitCount; break;
+ case glslang::EOpSubgroupBallotFindLSB: opCode = spv::OpGroupNonUniformBallotFindLSB; break;
+ case glslang::EOpSubgroupBallotFindMSB: opCode = spv::OpGroupNonUniformBallotFindMSB; break;
+ case glslang::EOpSubgroupShuffle: opCode = spv::OpGroupNonUniformShuffle; break;
+ case glslang::EOpSubgroupShuffleXor: opCode = spv::OpGroupNonUniformShuffleXor; break;
+ case glslang::EOpSubgroupShuffleUp: opCode = spv::OpGroupNonUniformShuffleUp; break;
+ case glslang::EOpSubgroupShuffleDown: opCode = spv::OpGroupNonUniformShuffleDown; break;
+ case glslang::EOpSubgroupAdd:
+ case glslang::EOpSubgroupInclusiveAdd:
+ case glslang::EOpSubgroupExclusiveAdd:
+ case glslang::EOpSubgroupClusteredAdd:
+ if (isFloat) {
+ opCode = spv::OpGroupNonUniformFAdd;
+ } else {
+ opCode = spv::OpGroupNonUniformIAdd;
+ }
+ break;
+ case glslang::EOpSubgroupMul:
+ case glslang::EOpSubgroupInclusiveMul:
+ case glslang::EOpSubgroupExclusiveMul:
+ case glslang::EOpSubgroupClusteredMul:
+ if (isFloat) {
+ opCode = spv::OpGroupNonUniformFMul;
+ } else {
+ opCode = spv::OpGroupNonUniformIMul;
+ }
+ break;
+ case glslang::EOpSubgroupMin:
+ case glslang::EOpSubgroupInclusiveMin:
+ case glslang::EOpSubgroupExclusiveMin:
+ case glslang::EOpSubgroupClusteredMin:
+ if (isFloat) {
+ opCode = spv::OpGroupNonUniformFMin;
+ } else if (isUnsigned) {
+ opCode = spv::OpGroupNonUniformUMin;
+ } else {
+ opCode = spv::OpGroupNonUniformSMin;
+ }
+ break;
+ case glslang::EOpSubgroupMax:
+ case glslang::EOpSubgroupInclusiveMax:
+ case glslang::EOpSubgroupExclusiveMax:
+ case glslang::EOpSubgroupClusteredMax:
+ if (isFloat) {
+ opCode = spv::OpGroupNonUniformFMax;
+ } else if (isUnsigned) {
+ opCode = spv::OpGroupNonUniformUMax;
+ } else {
+ opCode = spv::OpGroupNonUniformSMax;
+ }
+ break;
+ case glslang::EOpSubgroupAnd:
+ case glslang::EOpSubgroupInclusiveAnd:
+ case glslang::EOpSubgroupExclusiveAnd:
+ case glslang::EOpSubgroupClusteredAnd:
+ if (isBool) {
+ opCode = spv::OpGroupNonUniformLogicalAnd;
+ } else {
+ opCode = spv::OpGroupNonUniformBitwiseAnd;
+ }
+ break;
+ case glslang::EOpSubgroupOr:
+ case glslang::EOpSubgroupInclusiveOr:
+ case glslang::EOpSubgroupExclusiveOr:
+ case glslang::EOpSubgroupClusteredOr:
+ if (isBool) {
+ opCode = spv::OpGroupNonUniformLogicalOr;
+ } else {
+ opCode = spv::OpGroupNonUniformBitwiseOr;
+ }
+ break;
+ case glslang::EOpSubgroupXor:
+ case glslang::EOpSubgroupInclusiveXor:
+ case glslang::EOpSubgroupExclusiveXor:
+ case glslang::EOpSubgroupClusteredXor:
+ if (isBool) {
+ opCode = spv::OpGroupNonUniformLogicalXor;
+ } else {
+ opCode = spv::OpGroupNonUniformBitwiseXor;
+ }
+ break;
+ case glslang::EOpSubgroupQuadBroadcast: opCode = spv::OpGroupNonUniformQuadBroadcast; break;
+ case glslang::EOpSubgroupQuadSwapHorizontal:
+ case glslang::EOpSubgroupQuadSwapVertical:
+ case glslang::EOpSubgroupQuadSwapDiagonal: opCode = spv::OpGroupNonUniformQuadSwap; break;
+ default: assert(0 && "Unhandled subgroup operation!");
+ }
+
+ std::vector<spv::Id> spvGroupOperands;
+
+ // Every operation begins with the Execution Scope operand.
+ spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+
+ // Next, for all operations that use a Group Operation, push that as an operand.
+ switch (op) {
+ default: break;
+ case glslang::EOpSubgroupBallotBitCount:
+ case glslang::EOpSubgroupAdd:
+ case glslang::EOpSubgroupMul:
+ case glslang::EOpSubgroupMin:
+ case glslang::EOpSubgroupMax:
+ case glslang::EOpSubgroupAnd:
+ case glslang::EOpSubgroupOr:
+ case glslang::EOpSubgroupXor:
+ spvGroupOperands.push_back(spv::GroupOperationReduce);
+ break;
+ case glslang::EOpSubgroupBallotInclusiveBitCount:
+ case glslang::EOpSubgroupInclusiveAdd:
+ case glslang::EOpSubgroupInclusiveMul:
+ case glslang::EOpSubgroupInclusiveMin:
+ case glslang::EOpSubgroupInclusiveMax:
+ case glslang::EOpSubgroupInclusiveAnd:
+ case glslang::EOpSubgroupInclusiveOr:
+ case glslang::EOpSubgroupInclusiveXor:
+ spvGroupOperands.push_back(spv::GroupOperationInclusiveScan);
+ break;
+ case glslang::EOpSubgroupBallotExclusiveBitCount:
+ case glslang::EOpSubgroupExclusiveAdd:
+ case glslang::EOpSubgroupExclusiveMul:
+ case glslang::EOpSubgroupExclusiveMin:
+ case glslang::EOpSubgroupExclusiveMax:
+ case glslang::EOpSubgroupExclusiveAnd:
+ case glslang::EOpSubgroupExclusiveOr:
+ case glslang::EOpSubgroupExclusiveXor:
+ spvGroupOperands.push_back(spv::GroupOperationExclusiveScan);
+ break;
+ case glslang::EOpSubgroupClusteredAdd:
+ case glslang::EOpSubgroupClusteredMul:
+ case glslang::EOpSubgroupClusteredMin:
+ case glslang::EOpSubgroupClusteredMax:
+ case glslang::EOpSubgroupClusteredAnd:
+ case glslang::EOpSubgroupClusteredOr:
+ case glslang::EOpSubgroupClusteredXor:
+ spvGroupOperands.push_back(spv::GroupOperationClusteredReduce);
+ break;
+ }
+
+ // Push back the operands next.
+ for (auto opIt : operands) {
+ spvGroupOperands.push_back(opIt);
+ }
+
+ // Some opcodes have additional operands.
+ switch (op) {
+ default: break;
+ case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break;
+ case glslang::EOpSubgroupQuadSwapVertical: spvGroupOperands.push_back(builder.makeUintConstant(1)); break;
+ case glslang::EOpSubgroupQuadSwapDiagonal: spvGroupOperands.push_back(builder.makeUintConstant(2)); break;
+ }
+
+ return builder.createOp(opCode, typeId, spvGroupOperands);
+}
+
spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
-#ifdef AMD_EXTENSIONS
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64 || typeProxy == glslang::EbtUint16;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble || typeProxy == glslang::EbtFloat16;
-#else
- bool isUnsigned = typeProxy == glslang::EbtUint || typeProxy == glslang::EbtUint64;
- bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
-#endif
+ bool isUnsigned = isTypeUnsignedInt(typeProxy);
+ bool isFloat = isTypeFloat(typeProxy);
spv::Op opCode = spv::OpNop;
int extBuiltins = -1;
@@ -5422,11 +5870,7 @@
libCall = spv::GLSLstd450FrexpStruct;
assert(builder.isPointerType(typeId1));
typeId1 = builder.getContainedTypeId(typeId1);
-#ifdef AMD_EXTENSIONS
int width = builder.getScalarTypeWidth(typeId1);
-#else
- int width = 32;
-#endif
if (builder.getNumComponents(operands[0]) == 1)
frexpIntType = builder.makeIntegerType(width, true);
else
@@ -5442,6 +5886,22 @@
case glslang::EOpReadInvocation:
return createInvocationsOperation(op, typeId, operands, typeProxy);
+ case glslang::EOpSubgroupBroadcast:
+ case glslang::EOpSubgroupBallotBitExtract:
+ case glslang::EOpSubgroupShuffle:
+ case glslang::EOpSubgroupShuffleXor:
+ case glslang::EOpSubgroupShuffleUp:
+ case glslang::EOpSubgroupShuffleDown:
+ case glslang::EOpSubgroupClusteredAdd:
+ case glslang::EOpSubgroupClusteredMul:
+ case glslang::EOpSubgroupClusteredMin:
+ case glslang::EOpSubgroupClusteredMax:
+ case glslang::EOpSubgroupClusteredAnd:
+ case glslang::EOpSubgroupClusteredOr:
+ case glslang::EOpSubgroupClusteredXor:
+ case glslang::EOpSubgroupQuadBroadcast:
+ return createSubgroupOperation(op, typeId, operands, typeProxy);
+
#ifdef AMD_EXTENSIONS
case glslang::EOpSwizzleInvocations:
extBuiltins = getExtBuiltins(spv::E_SPV_AMD_shader_ballot);
@@ -5634,6 +6094,30 @@
spv::MemorySemanticsWorkgroupMemoryMask |
spv::MemorySemanticsAcquireReleaseMask);
return 0;
+ case glslang::EOpSubgroupBarrier:
+ builder.createControlBarrier(spv::ScopeSubgroup, spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+ spv::MemorySemanticsAcquireReleaseMask);
+ return spv::NoResult;
+ case glslang::EOpSubgroupMemoryBarrier:
+ builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsAllMemory |
+ spv::MemorySemanticsAcquireReleaseMask);
+ return spv::NoResult;
+ case glslang::EOpSubgroupMemoryBarrierBuffer:
+ builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsUniformMemoryMask |
+ spv::MemorySemanticsAcquireReleaseMask);
+ return spv::NoResult;
+ case glslang::EOpSubgroupMemoryBarrierImage:
+ builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsImageMemoryMask |
+ spv::MemorySemanticsAcquireReleaseMask);
+ return spv::NoResult;
+ case glslang::EOpSubgroupMemoryBarrierShared:
+ builder.createMemoryBarrier(spv::ScopeSubgroup, spv::MemorySemanticsWorkgroupMemoryMask |
+ spv::MemorySemanticsAcquireReleaseMask);
+ return spv::NoResult;
+ case glslang::EOpSubgroupElect: {
+ std::vector<spv::Id> operands;
+ return createSubgroupOperation(op, typeId, operands, glslang::EbtVoid);
+ }
#ifdef AMD_EXTENSIONS
case glslang::EOpTime:
{
@@ -5876,6 +6360,18 @@
for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
bool zero = nextConst >= consts.size();
switch (glslangType.getBasicType()) {
+ case glslang::EbtInt8:
+ spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
+ break;
+ case glslang::EbtUint8:
+ spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const()));
+ break;
+ case glslang::EbtInt16:
+ spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const()));
+ break;
+ case glslang::EbtUint16:
+ spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const()));
+ break;
case glslang::EbtInt:
spvConsts.push_back(builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst()));
break;
@@ -5888,25 +6384,15 @@
case glslang::EbtUint64:
spvConsts.push_back(builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const()));
break;
-#ifdef AMD_EXTENSIONS
- case glslang::EbtInt16:
- spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst()));
- break;
- case glslang::EbtUint16:
- spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst()));
- break;
-#endif
case glslang::EbtFloat:
spvConsts.push_back(builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
break;
case glslang::EbtDouble:
spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst()));
break;
-#ifdef AMD_EXTENSIONS
case glslang::EbtFloat16:
spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
break;
-#endif
case glslang::EbtBool:
spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
break;
@@ -5921,6 +6407,18 @@
bool zero = nextConst >= consts.size();
spv::Id scalar = 0;
switch (glslangType.getBasicType()) {
+ case glslang::EbtInt8:
+ scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
+ break;
+ case glslang::EbtUint8:
+ scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant);
+ break;
+ case glslang::EbtInt16:
+ scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant);
+ break;
+ case glslang::EbtUint16:
+ scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant);
+ break;
case glslang::EbtInt:
scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant);
break;
@@ -5933,25 +6431,15 @@
case glslang::EbtUint64:
scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
break;
-#ifdef AMD_EXTENSIONS
- case glslang::EbtInt16:
- scalar = builder.makeInt16Constant(zero ? 0 : (short)consts[nextConst].getIConst(), specConstant);
- break;
- case glslang::EbtUint16:
- scalar = builder.makeUint16Constant(zero ? 0 : (unsigned short)consts[nextConst].getUConst(), specConstant);
- break;
-#endif
case glslang::EbtFloat:
scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
break;
case glslang::EbtDouble:
scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
break;
-#ifdef AMD_EXTENSIONS
case glslang::EbtFloat16:
scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
break;
-#endif
case glslang::EbtBool:
scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
break;