SPIR-V: Move from Version .99 Rev 31 to Version 1.0, Rev 2.
diff --git a/SPIRV/GLSL.std.450.h b/SPIRV/GLSL.std.450.h
index 13bb8e3..d1c9b5c 100755
--- a/SPIRV/GLSL.std.450.h
+++ b/SPIRV/GLSL.std.450.h
@@ -28,7 +28,7 @@
#define GLSLstd450_H
const int GLSLstd450Version = 99;
-const int GLSLstd450Revision = 2;
+const int GLSLstd450Revision = 3;
enum GLSLstd450 {
GLSLstd450Bad = 0, // Don't use
@@ -82,47 +82,44 @@
GLSLstd450FClamp = 43,
GLSLstd450UClamp = 44,
GLSLstd450SClamp = 45,
- GLSLstd450Mix = 46,
- GLSLstd450Step = 47,
- GLSLstd450SmoothStep = 48,
+ GLSLstd450FMix = 46,
+ GLSLstd450IMix = 47,
+ GLSLstd450Step = 48,
+ GLSLstd450SmoothStep = 49,
- GLSLstd450Fma = 49,
- GLSLstd450Frexp = 50, // second operand needs an OpVariable to write to
- GLSLstd450FrexpStruct = 51, // no OpVariable operand
- GLSLstd450Ldexp = 52,
+ GLSLstd450Fma = 50,
+ GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
+ GLSLstd450FrexpStruct = 52, // no OpVariable operand
+ GLSLstd450Ldexp = 53,
- GLSLstd450PackSnorm4x8 = 53,
- GLSLstd450PackUnorm4x8 = 54,
- GLSLstd450PackSnorm2x16 = 55,
- GLSLstd450PackUnorm2x16 = 56,
- GLSLstd450PackHalf2x16 = 57,
- GLSLstd450PackDouble2x32 = 58,
- GLSLstd450UnpackSnorm2x16 = 59,
- GLSLstd450UnpackUnorm2x16 = 60,
- GLSLstd450UnpackHalf2x16 = 61,
- GLSLstd450UnpackSnorm4x8 = 62,
- GLSLstd450UnpackUnorm4x8 = 63,
- GLSLstd450UnpackDouble2x32 = 64,
+ GLSLstd450PackSnorm4x8 = 54,
+ GLSLstd450PackUnorm4x8 = 55,
+ GLSLstd450PackSnorm2x16 = 56,
+ GLSLstd450PackUnorm2x16 = 57,
+ GLSLstd450PackHalf2x16 = 58,
+ GLSLstd450PackDouble2x32 = 59,
+ GLSLstd450UnpackSnorm2x16 = 60,
+ GLSLstd450UnpackUnorm2x16 = 61,
+ GLSLstd450UnpackHalf2x16 = 62,
+ GLSLstd450UnpackSnorm4x8 = 63,
+ GLSLstd450UnpackUnorm4x8 = 64,
+ GLSLstd450UnpackDouble2x32 = 65,
- GLSLstd450Length = 65,
- GLSLstd450Distance = 66,
- GLSLstd450Cross = 67,
- GLSLstd450Normalize = 68,
- GLSLstd450FaceForward = 69,
- GLSLstd450Reflect = 70,
- GLSLstd450Refract = 71,
+ GLSLstd450Length = 66,
+ GLSLstd450Distance = 67,
+ GLSLstd450Cross = 68,
+ GLSLstd450Normalize = 69,
+ GLSLstd450FaceForward = 70,
+ GLSLstd450Reflect = 71,
+ GLSLstd450Refract = 72,
- GLSLstd450FindILSB = 72,
- GLSLstd450FindSMSB = 73,
- GLSLstd450FindUMSB = 74,
+ GLSLstd450FindILsb = 73,
+ GLSLstd450FindSMsb = 74,
+ GLSLstd450FindUMsb = 75,
- GLSLstd450InterpolateAtCentroid = 75,
- GLSLstd450InterpolateAtSample = 76,
- GLSLstd450InterpolateAtOffset = 77,
-
- GLSLstd450AddCarry = 78, // These three should move to the core instruction set
- GLSLstd450SubBorrow = 79,
- GLSLstd450MulExtended = 80,
+ GLSLstd450InterpolateAtCentroid = 76,
+ GLSLstd450InterpolateAtSample = 77,
+ GLSLstd450InterpolateAtOffset = 78,
GLSLstd450Count
};
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index c005197..c5342ac 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -60,7 +60,10 @@
namespace {
-const int GlslangMagic = 0x51a;
+// For low-order part of the generator's magic number. Bump up
+// when there is a change in the style (e.g., if SSA form changes,
+// or a different instruction sequence to do something gets used).
+const int GeneratorVersion = 1;
//
// The main holder of information for translating glslang to SPIR-V.
@@ -113,13 +116,16 @@
spv::Id createNoArgOperation(glslang::TOperator op);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
void addDecoration(spv::Id id, spv::Decoration dec);
+ void addDecoration(spv::Id id, spv::Decoration dec, unsigned value);
void addMemberDecoration(spv::Id id, int member, spv::Decoration dec);
- spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst);
+ spv::Id createSpvSpecConstant(const glslang::TIntermTyped&);
+ spv::Id createSpvConstant(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant);
bool isTrivialLeaf(const glslang::TIntermTyped* node);
bool isTrivial(const glslang::TIntermTyped* node);
spv::Id createShortCircuit(glslang::TOperator, glslang::TIntermTyped& left, glslang::TIntermTyped& right);
spv::Function* shaderEntry;
+ spv::Instruction* entryPoint;
int sequenceDepth;
// There is a 1:1 mapping between a spv builder and a module; this is thread safe
@@ -169,7 +175,7 @@
case EShLangFragment: return spv::ExecutionModelFragment;
case EShLangCompute: return spv::ExecutionModelGLCompute;
default:
- spv::MissingFunctionality("GLSL stage");
+ assert(0);
return spv::ExecutionModelFragment;
}
}
@@ -191,12 +197,12 @@
// TODO: how are we distuingishing between default and non-default non-writable uniforms? Do default uniforms even exist?
} else {
switch (type.getQualifier().storage) {
- case glslang::EvqShared: return spv::StorageClassWorkgroupLocal; break;
- case glslang::EvqGlobal: return spv::StorageClassPrivateGlobal;
+ case glslang::EvqShared: return spv::StorageClassWorkgroup; break;
+ case glslang::EvqGlobal: return spv::StorageClassPrivate;
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
case glslang::EvqTemporary: return spv::StorageClassFunction;
default:
- spv::MissingFunctionality("unknown glslang storage class");
+ assert(0);
return spv::StorageClassFunction;
}
}
@@ -206,14 +212,14 @@
spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
{
switch (sampler.dim) {
- case glslang::Esd1D: return spv::Dim1D;
- case glslang::Esd2D: return spv::Dim2D;
- case glslang::Esd3D: return spv::Dim3D;
- case glslang::EsdCube: return spv::DimCube;
- case glslang::EsdRect: return spv::DimRect;
- case glslang::EsdBuffer: return spv::DimBuffer;
+ case glslang::Esd1D: return spv::Dim1D;
+ case glslang::Esd2D: return spv::Dim2D;
+ case glslang::Esd3D: return spv::Dim3D;
+ case glslang::EsdCube: return spv::DimCube;
+ case glslang::EsdRect: return spv::DimRect;
+ case glslang::EsdBuffer: return spv::DimBuffer;
default:
- spv::MissingFunctionality("unknown sampler dimension");
+ assert(0);
return spv::Dim2D;
}
}
@@ -240,7 +246,7 @@
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
default:
- spv::MissingFunctionality("kind of block");
+ assert(0);
break;
}
}
@@ -275,11 +281,10 @@
}
case glslang::EvqVaryingIn:
case glslang::EvqVaryingOut:
- if (type.getQualifier().layoutPacking != glslang::ElpNone)
- spv::MissingFunctionality("in/out block layout");
+ assert(type.getQualifier().layoutPacking == glslang::ElpNone);
return (spv::Decoration)spv::BadValue;
default:
- spv::MissingFunctionality("block storage qualification");
+ assert(0);
return (spv::Decoration)spv::BadValue;
}
}
@@ -287,12 +292,16 @@
}
// Translate glslang type to SPIR-V interpolation decorations.
+// Returns spv::Decoration(spv::BadValue) when no decoration
+// should be applied.
spv::Decoration TranslateInterpolationDecoration(const glslang::TType& type)
{
- if (type.getQualifier().smooth)
- return spv::DecorationSmooth;
+ if (type.getQualifier().smooth) {
+ // Smooth decoration doesn't exist in SPIR-V 1.0
+ return (spv::Decoration)spv::BadValue;
+ }
if (type.getQualifier().nopersp)
- return spv::DecorationNoperspective;
+ return spv::DecorationNoPerspective;
else if (type.getQualifier().patch)
return spv::DecorationPatch;
else if (type.getQualifier().flat)
@@ -344,8 +353,6 @@
case glslang::EbvSampleId: return spv::BuiltInSampleId;
case glslang::EbvSamplePosition: return spv::BuiltInSamplePosition;
case glslang::EbvSampleMask: return spv::BuiltInSampleMask;
- case glslang::EbvFragColor: return spv::BuiltInFragColor;
- case glslang::EbvFragData: return spv::BuiltInFragColor;
case glslang::EbvFragDepth: return spv::BuiltInFragDepth;
case glslang::EbvHelperInvocation: return spv::BuiltInHelperInvocation;
case glslang::EbvNumWorkGroups: return spv::BuiltInNumWorkgroups;
@@ -414,7 +421,7 @@
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate)
: TIntermTraverser(true, false, true), shaderEntry(0), sequenceDepth(0),
- builder(GlslangMagic),
+ builder((glslang::GetKhronosToolId() << 16) | GeneratorVersion),
inMain(false), mainTerminated(false), linkageOnly(false),
glslangIntermediate(glslangIntermediate)
{
@@ -425,7 +432,7 @@
stdBuiltins = builder.import("GLSL.std.450");
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
shaderEntry = builder.makeMain();
- builder.addEntryPoint(executionModel, shaderEntry, "main");
+ entryPoint = builder.addEntryPoint(executionModel, shaderEntry, "main");
// Add the source extensions
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
@@ -451,9 +458,9 @@
case EShLangTessEvaluation:
builder.addCapability(spv::CapabilityTessellation);
switch (glslangIntermediate->getInputPrimitive()) {
- case glslang::ElgTriangles: mode = spv::ExecutionModeInputTriangles; break;
- case glslang::ElgQuads: mode = spv::ExecutionModeInputQuads; break;
- case glslang::ElgIsolines: mode = spv::ExecutionModeInputIsolines; break;
+ case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break;
+ case glslang::ElgQuads: mode = spv::ExecutionModeQuads; break;
+ case glslang::ElgIsolines: mode = spv::ExecutionModeIsolines; break;
default: mode = spv::BadValue; break;
}
if (mode != spv::BadValue)
@@ -486,7 +493,7 @@
case glslang::ElgPoints: mode = spv::ExecutionModeInputPoints; break;
case glslang::ElgLines: mode = spv::ExecutionModeInputLines; break;
case glslang::ElgLinesAdjacency: mode = spv::ExecutionModeInputLinesAdjacency; break;
- case glslang::ElgTriangles: mode = spv::ExecutionModeInputTriangles; break;
+ case glslang::ElgTriangles: mode = spv::ExecutionModeTriangles; break;
case glslang::ElgTrianglesAdjacency: mode = spv::ExecutionModeInputTrianglesAdjacency; break;
default: mode = spv::BadValue; break;
}
@@ -520,7 +527,6 @@
builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests);
switch(glslangIntermediate->getDepth()) {
- case glslang::EldAny: mode = spv::ExecutionModeDepthAny; break;
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
default: mode = spv::BadValue; break;
@@ -591,6 +597,11 @@
builder.setAccessChainRValue(id);
else
builder.setAccessChainLValue(id);
+ } else {
+ // finish off the entry-point SPV instruction by adding the Input/Output <id>
+ spv::StorageClass sc = builder.getStorageClass(id);
+ if (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)
+ entryPoint->addIdOperand(id);
}
}
@@ -639,8 +650,7 @@
node->getType().getBasicType());
// these all need their counterparts in createBinaryOperation()
- if (rValue == 0)
- spv::MissingFunctionality("createBinaryOperation");
+ assert(rValue != spv::NoResult);
}
// store the result
@@ -660,20 +670,13 @@
// Add the next element in the chain
- int index = 0;
- if (node->getRight()->getAsConstantUnion() == 0)
- spv::MissingFunctionality("direct index without a constant node");
- else
- index = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
-
+ int index = node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst();
if (node->getLeft()->getBasicType() == glslang::EbtBlock && node->getOp() == glslang::EOpIndexDirectStruct) {
// This may be, e.g., an anonymous block-member selection, which generally need
// index remapping due to hidden members in anonymous blocks.
std::vector<int>& remapper = memberRemapper[node->getLeft()->getType().getStruct()];
- if (remapper.size() == 0)
- spv::MissingFunctionality("block without member remapping");
- else
- index = remapper[index];
+ assert(remapper.size() > 0);
+ index = remapper[index];
}
if (! node->getLeft()->getType().isArray() &&
@@ -766,7 +769,7 @@
node->getLeft()->getType().getBasicType());
if (! result) {
- spv::MissingFunctionality("glslang binary operation");
+ spv::MissingFunctionality("unknown glslang binary operation");
} else {
builder.clearAccessChain();
builder.setAccessChainRValue(result);
@@ -832,7 +835,7 @@
// if not, then possibly an operation
if (! result)
- result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getBasicType());
+ result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operand, node->getOperand()->getBasicType());
if (result) {
builder.clearAccessChain();
@@ -862,8 +865,7 @@
spv::Id result = createBinaryOperation(op, TranslatePrecisionDecoration(node->getType()),
convertGlslangToSpvType(node->getType()), operand, one,
node->getType().getBasicType());
- if (result == 0)
- spv::MissingFunctionality("createBinaryOperation for unary");
+ assert(result != spv::NoResult);
// The result of operation is always stored, but conditionally the
// consumed result. The consumed result is always an r-value.
@@ -886,7 +888,7 @@
return false;
default:
- spv::MissingFunctionality("glslang unary");
+ spv::MissingFunctionality("unknown glslang unary");
break;
}
@@ -990,13 +992,7 @@
{
if (node->isUserDefined())
result = handleUserFunctionCall(node);
-
- if (! result) {
- spv::MissingFunctionality("glslang function call");
- glslang::TConstUnionArray emptyConsts;
- int nextConst = 0;
- result = createSpvConstant(node->getType(), emptyConsts, nextConst);
- }
+ assert(result);
builder.clearAccessChain();
builder.setAccessChainRValue(result);
@@ -1053,12 +1049,10 @@
for (int c = 0; c < (int)arguments.size(); ++c)
constituents.push_back(arguments[c]);
constructed = builder.createCompositeConstruct(resultTypeId, constituents);
- } else {
- if (isMatrix)
- constructed = builder.createMatrixConstructor(precision, arguments, resultTypeId);
- else
- constructed = builder.createConstructor(precision, arguments, resultTypeId);
- }
+ } else if (isMatrix)
+ constructed = builder.createMatrixConstructor(precision, arguments, resultTypeId);
+ else
+ constructed = builder.createConstructor(precision, arguments, resultTypeId);
builder.clearAccessChain();
builder.setAccessChainRValue(constructed);
@@ -1131,21 +1125,6 @@
atomic = true;
break;
- case glslang::EOpAddCarry:
- case glslang::EOpSubBorrow:
- case glslang::EOpUMulExtended:
- case glslang::EOpIMulExtended:
- case glslang::EOpBitfieldExtract:
- case glslang::EOpBitfieldInsert:
- spv::MissingFunctionality("integer aggregate");
- break;
-
- case glslang::EOpFma:
- case glslang::EOpFrexp:
- case glslang::EOpLdexp:
- spv::MissingFunctionality("fma/frexp/ldexp aggregate");
- break;
-
default:
break;
}
@@ -1171,9 +1150,7 @@
left->getType().getBasicType(), reduceComparison);
// code above should only make binOp that exists in createBinaryOperation
- if (result == 0)
- spv::MissingFunctionality("createBinaryOperation for aggregate");
-
+ assert(result != spv::NoResult);
builder.clearAccessChain();
builder.setAccessChainRValue(result);
@@ -1192,7 +1169,7 @@
// special case l-value operands; there are just a few
bool lvalue = false;
switch (node->getOp()) {
- //case glslang::EOpFrexp:
+ case glslang::EOpFrexp:
case glslang::EOpModf:
if (arg == 1)
lvalue = true;
@@ -1208,9 +1185,16 @@
if (arg == 0)
lvalue = true;
break;
- //case glslang::EOpUAddCarry:
- //case glslang::EOpUSubBorrow:
- //case glslang::EOpUMulExtended:
+ case glslang::EOpAddCarry:
+ case glslang::EOpSubBorrow:
+ if (arg == 2)
+ lvalue = true;
+ break;
+ case glslang::EOpUMulExtended:
+ case glslang::EOpIMulExtended:
+ if (arg >= 2)
+ lvalue = true;
+ break;
default:
break;
}
@@ -1230,7 +1214,7 @@
result = createNoArgOperation(node->getOp());
break;
case 1:
- result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType());
+ result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), glslangOperands[0]->getAsTyped()->getBasicType());
break;
default:
result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
@@ -1242,7 +1226,7 @@
return false;
if (! result) {
- spv::MissingFunctionality("glslang aggregate");
+ spv::MissingFunctionality("unknown glslang aggregate");
return true;
} else {
builder.clearAccessChain();
@@ -1350,7 +1334,7 @@
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
{
int nextConst = 0;
- spv::Id constant = createSpvConstant(node->getType(), node->getConstArray(), nextConst);
+ spv::Id constant = createSpvConstant(node->getType(), node->getConstArray(), nextConst, false);
builder.clearAccessChain();
builder.setAccessChainRValue(constant);
@@ -1418,7 +1402,7 @@
break;
default:
- spv::MissingFunctionality("branch type");
+ assert(0);
break;
}
@@ -1429,9 +1413,9 @@
{
// First, steer off constants, which are not SPIR-V variables, but
// can still have a mapping to a SPIR-V Id.
+ // This includes specialization constants.
if (node->getQualifier().storage == glslang::EvqConst) {
- int nextConst = 0;
- return createSpvConstant(node->getType(), node->getConstArray(), nextConst);
+ return createSpvSpecConstant(*node);
}
// Now, handle actual variables
@@ -1453,7 +1437,7 @@
case glslang::EbtInt: return builder.makeIntType(32);
case glslang::EbtUint: return builder.makeUintType(32);
default:
- spv::MissingFunctionality("sampled type");
+ assert(0);
return builder.makeFloatType(32);
}
}
@@ -1474,8 +1458,7 @@
switch (type.getBasicType()) {
case glslang::EbtVoid:
spvType = builder.makeVoidType();
- if (type.isArray())
- spv::MissingFunctionality("array of void");
+ assert (! type.isArray());
break;
case glslang::EbtFloat:
spvType = builder.makeFloatType(32);
@@ -1499,12 +1482,13 @@
case glslang::EbtSampler:
{
const glslang::TSampler& sampler = type.getSampler();
- spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms,
- sampler.image ? 2 : 1, TranslateImageFormat(type));
- // OpenGL "textures" need to be combined with a sampler
- if (! sampler.image)
- spvType = builder.makeSampledImageType(spvType);
- }
+ // an image is present, make its type
+ spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms,
+ sampler.image ? 2 : 1, TranslateImageFormat(type));
+ if (! sampler.image) {
+ spvType = builder.makeSampledImageType(spvType);
+ }
+ }
break;
case glslang::EbtStruct:
case glslang::EbtBlock:
@@ -1593,7 +1577,7 @@
}
break;
default:
- spv::MissingFunctionality("basic type");
+ assert(0);
break;
}
@@ -1620,10 +1604,14 @@
spvType = builder.makeArrayType(spvType, type.getOuterArraySize());
}
- // TODO: layout still needs to be done hierarchically for arrays of arrays, which
+ // TODO: explicit layout still needs to be done hierarchically for arrays of arrays, which
// may still require additional "link time" support from the front-end
// for arrays of arrays
- if (explicitLayout)
+
+ // We need to decorate array strides for types needing explicit layout,
+ // except for the very top if it is an array of blocks; that array is
+ // not laid out in memory in a way needing a stride.
+ if (explicitLayout && type.getBasicType() != glslang::EbtBlock)
builder.addDecoration(spvType, spv::DecorationArrayStride, getArrayStride(type));
}
@@ -1883,8 +1871,11 @@
operands.push_back(*(opIt++));
if (node->getOp() == glslang::EOpImageStore)
operands.push_back(*(opIt++));
- // TODO: add 'sample' operand
if (node->getOp() == glslang::EOpImageLoad) {
+ if (sampler.ms) {
+ operands.push_back(spv::ImageOperandsSampleMask);
+ operands.push_back(*(opIt++));
+ }
return builder.createOp(spv::OpImageRead, convertGlslangToSpvType(node->getType()), operands);
} else if (node->getOp() == glslang::EOpImageStore) {
builder.createNoResultOp(spv::OpImageWrite, operands);
@@ -1909,8 +1900,6 @@
}
// Check for texture functions other than queries
- if (cracked.gather)
- spv::MissingFunctionality("texture gather");
// check for bias argument
bool bias = false;
@@ -1925,14 +1914,18 @@
bias = true;
}
- bool cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
-
// set the rest of the arguments
+
params.coords = arguments[1];
int extraArgs = 0;
- if (cubeCompare)
+
+ // sort out where Dref is coming from
+ if (sampler.shadow && sampler.dim == glslang::EsdCube && sampler.arrayed)
params.Dref = arguments[2];
- else if (sampler.shadow) {
+ else if (sampler.shadow && cracked.gather) {
+ params.Dref = arguments[2];
+ ++extraArgs;
+ } else if (sampler.shadow) {
std::vector<spv::Id> indexes;
int comp;
if (cracked.proj)
@@ -1954,20 +1947,28 @@
params.gradY = arguments[3 + extraArgs];
extraArgs += 2;
}
- //if (gather && compare) {
- // params.compare = arguments[2 + extraArgs];
- // ++extraArgs;
- //}
- if (cracked.offset || cracked.offsets) {
+ if (cracked.offset) {
params.offset = arguments[2 + extraArgs];
++extraArgs;
+ } else if (cracked.offsets) {
+ params.offsets = arguments[2 + extraArgs];
+ ++extraArgs;
}
if (bias) {
params.bias = arguments[2 + extraArgs];
++extraArgs;
}
+ if (cracked.gather && ! sampler.shadow) {
+ // default component is 0, if missing, otherwise an argument
+ if (2 + extraArgs < (int)arguments.size()) {
+ params.comp = arguments[2 + extraArgs];
+ ++extraArgs;
+ } else {
+ params.comp = builder.makeIntConstant(0);
+ }
+ }
- return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), cracked.fetch, cracked.proj, params);
+ return builder.createTextureCall(precision, convertGlslangToSpvType(node->getType()), cracked.fetch, cracked.proj, cracked.gather, params);
}
spv::Id TGlslangToSpvTraverser::handleUserFunctionCall(const glslang::TIntermAggregate* node)
@@ -2308,6 +2309,7 @@
{
spv::Op unaryOp = spv::OpNop;
int libCall = -1;
+ bool isUnsigned = typeProxy == glslang::EbtUint;
bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
switch (op) {
@@ -2538,11 +2540,13 @@
unaryOp = spv::OpBitCount;
break;
case glslang::EOpFindLSB:
- libCall = spv::GLSLstd450FindILSB;
+ libCall = spv::GLSLstd450FindILsb;
break;
case glslang::EOpFindMSB:
- spv::MissingFunctionality("signed vs. unsigned FindMSB");
- libCall = spv::GLSLstd450FindSMSB;
+ if (isUnsigned)
+ libCall = spv::GLSLstd450FindUMsb;
+ else
+ libCall = spv::GLSLstd450FindSMsb;
break;
default:
@@ -2717,7 +2721,7 @@
opCode = spv::OpAtomicLoad;
break;
default:
- spv::MissingFunctionality("missing nested atomic");
+ assert(0);
break;
}
@@ -2754,6 +2758,11 @@
spv::Op opCode = spv::OpNop;
int libCall = -1;
+ int consumedOperands = operands.size();
+ spv::Id typeId0 = 0;
+ if (consumedOperands > 0)
+ typeId0 = builder.getTypeId(operands[0]);
+ spv::Id frexpIntType = 0;
switch (op) {
case glslang::EOpMin:
@@ -2794,7 +2803,10 @@
libCall = spv::GLSLstd450SClamp;
break;
case glslang::EOpMix:
- libCall = spv::GLSLstd450Mix;
+ if (isFloat)
+ libCall = spv::GLSLstd450FMix;
+ else
+ libCall = spv::GLSLstd450IMix;
break;
case glslang::EOpStep:
libCall = spv::GLSLstd450Step;
@@ -2819,6 +2831,52 @@
libCall = spv::GLSLstd450Refract;
break;
+ case glslang::EOpAddCarry:
+ opCode = spv::OpIAddCarry;
+ typeId = builder.makeStructResultType(typeId0, typeId0);
+ consumedOperands = 2;
+ break;
+ case glslang::EOpSubBorrow:
+ opCode = spv::OpISubBorrow;
+ typeId = builder.makeStructResultType(typeId0, typeId0);
+ consumedOperands = 2;
+ break;
+ case glslang::EOpUMulExtended:
+ opCode = spv::OpUMulExtended;
+ typeId = builder.makeStructResultType(typeId0, typeId0);
+ consumedOperands = 2;
+ break;
+ case glslang::EOpIMulExtended:
+ opCode = spv::OpSMulExtended;
+ typeId = builder.makeStructResultType(typeId0, typeId0);
+ consumedOperands = 2;
+ break;
+ case glslang::EOpBitfieldExtract:
+ if (isUnsigned)
+ opCode = spv::OpBitFieldUExtract;
+ else
+ opCode = spv::OpBitFieldSExtract;
+ break;
+ case glslang::EOpBitfieldInsert:
+ opCode = spv::OpBitFieldInsert;
+ break;
+
+ case glslang::EOpFma:
+ libCall = spv::GLSLstd450Fma;
+ break;
+ case glslang::EOpFrexp:
+ libCall = spv::GLSLstd450FrexpStruct;
+ if (builder.getNumComponents(operands[0]) == 1)
+ frexpIntType = builder.makeIntegerType(32, true);
+ else
+ frexpIntType = builder.makeVectorType(builder.makeIntegerType(32, true), builder.getNumComponents(operands[0]));
+ typeId = builder.makeStructResultType(typeId0, frexpIntType);
+ consumedOperands = 1;
+ break;
+ case glslang::EOpLdexp:
+ libCall = spv::GLSLstd450Ldexp;
+ break;
+
default:
return 0;
}
@@ -2827,7 +2885,7 @@
if (libCall >= 0)
id = builder.createBuiltinCall(precision, typeId, stdBuiltins, libCall, operands);
else {
- switch (operands.size()) {
+ switch (consumedOperands) {
case 0:
// should all be handled by visitAggregate and createNoArgOperation
assert(0);
@@ -2839,16 +2897,34 @@
case 2:
id = builder.createBinOp(opCode, typeId, operands[0], operands[1]);
break;
- case 3:
- id = builder.createTriOp(opCode, typeId, operands[0], operands[1], operands[2]);
- break;
default:
- // These do not exist yet
- assert(0 && "operation with more than 3 operands");
+ // anything 3 or over doesn't have l-value operands, so all should be consumed
+ assert(consumedOperands == operands.size());
+ id = builder.createOp(opCode, typeId, operands);
break;
}
}
+ // Decode the return types that were structures
+ switch (op) {
+ case glslang::EOpAddCarry:
+ case glslang::EOpSubBorrow:
+ builder.createStore(builder.createCompositeExtract(id, typeId0, 1), operands[2]);
+ id = builder.createCompositeExtract(id, typeId0, 0);
+ break;
+ case glslang::EOpUMulExtended:
+ case glslang::EOpIMulExtended:
+ builder.createStore(builder.createCompositeExtract(id, typeId0, 0), operands[3]);
+ builder.createStore(builder.createCompositeExtract(id, typeId0, 1), operands[2]);
+ break;
+ case glslang::EOpFrexp:
+ builder.createStore(builder.createCompositeExtract(id, frexpIntType, 1), operands[1]);
+ id = builder.createCompositeExtract(id, typeId0, 0);
+ break;
+ default:
+ break;
+ }
+
builder.setPrecision(id, precision);
return id;
@@ -2883,13 +2959,13 @@
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask);
return 0;
case glslang::EOpMemoryBarrierShared:
- builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupLocalMemoryMask);
+ builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask);
return 0;
case glslang::EOpGroupMemoryBarrier:
- builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupGlobalMemoryMask);
+ builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsCrossWorkgroupMemoryMask);
return 0;
default:
- spv::MissingFunctionality("operation with no arguments");
+ spv::MissingFunctionality("unknown operation with no arguments");
return 0;
}
}
@@ -2945,31 +3021,57 @@
if (builtIn != spv::BadValue)
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
- if (linkageOnly)
- builder.addDecoration(id, spv::DecorationNoStaticUse);
-
return id;
}
+// If 'dec' is valid, add no-operand decoration to an object
void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec)
{
if (dec != spv::BadValue)
builder.addDecoration(id, dec);
}
+// If 'dec' is valid, add a one-operand decoration to an object
+void TGlslangToSpvTraverser::addDecoration(spv::Id id, spv::Decoration dec, unsigned value)
+{
+ if (dec != spv::BadValue)
+ builder.addDecoration(id, dec, value);
+}
+
+// If 'dec' is valid, add a no-operand decoration to a struct member
void TGlslangToSpvTraverser::addMemberDecoration(spv::Id id, int member, spv::Decoration dec)
{
if (dec != spv::BadValue)
builder.addMemberDecoration(id, (unsigned)member, dec);
}
+// Make a full tree of instructions to build a SPIR-V specialization constant,
+// or regularly constant if possible.
+//
+// TBD: this is not yet done, nor verified to be the best design, it does do the leaf symbols though
+//
+// Recursively walk the nodes. The nodes form a tree whose leaves are
+// regular constants, which themselves are trees that createSpvConstant()
+// recursively walks. So, this function walks the "top" of the tree:
+// - emit specialization constant-building instructions for specConstant
+// - when running into a non-spec-constant, switch to createSpvConstant()
+spv::Id TGlslangToSpvTraverser::createSpvSpecConstant(const glslang::TIntermTyped& node)
+{
+ assert(node.getQualifier().storage == glslang::EvqConst);
+
+ // hand off to the non-spec-constant path
+ assert(node.getAsConstantUnion() != nullptr || node.getAsSymbolNode() != nullptr);
+ int nextConst = 0;
+ return createSpvConstant(node.getType(), node.getAsConstantUnion() ? node.getAsConstantUnion()->getConstArray() : node.getAsSymbolNode()->getConstArray(), nextConst, false);
+}
+
// Use 'consts' as the flattened glslang source of scalar constants to recursively
// build the aggregate SPIR-V constant.
//
// If there are not enough elements present in 'consts', 0 will be substituted;
// an empty 'consts' can be used to create a fully zeroed SPIR-V constant.
//
-spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst)
+spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TType& glslangType, const glslang::TConstUnionArray& consts, int& nextConst, bool specConstant)
{
// vector of constants for SPIR-V
std::vector<spv::Id> spvConsts;
@@ -2980,15 +3082,15 @@
if (glslangType.isArray()) {
glslang::TType elementType(glslangType, 0);
for (int i = 0; i < glslangType.getOuterArraySize(); ++i)
- spvConsts.push_back(createSpvConstant(elementType, consts, nextConst));
+ spvConsts.push_back(createSpvConstant(elementType, consts, nextConst, false));
} else if (glslangType.isMatrix()) {
glslang::TType vectorType(glslangType, 0);
for (int col = 0; col < glslangType.getMatrixCols(); ++col)
- spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst));
+ spvConsts.push_back(createSpvConstant(vectorType, consts, nextConst, false));
} else if (glslangType.getStruct()) {
glslang::TVector<glslang::TTypeLoc>::const_iterator iter;
for (iter = glslangType.getStruct()->begin(); iter != glslangType.getStruct()->end(); ++iter)
- spvConsts.push_back(createSpvConstant(*iter->type, consts, nextConst));
+ spvConsts.push_back(createSpvConstant(*iter->type, consts, nextConst, false));
} else if (glslangType.isVector()) {
for (unsigned int i = 0; i < (unsigned int)glslangType.getVectorSize(); ++i) {
bool zero = nextConst >= consts.size();
@@ -3009,7 +3111,7 @@
spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
break;
default:
- spv::MissingFunctionality("constant vector type");
+ assert(0);
break;
}
++nextConst;
@@ -3020,22 +3122,22 @@
spv::Id scalar = 0;
switch (glslangType.getBasicType()) {
case glslang::EbtInt:
- scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst());
+ scalar = builder.makeIntConstant(zero ? 0 : consts[nextConst].getIConst(), specConstant);
break;
case glslang::EbtUint:
- scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst());
+ scalar = builder.makeUintConstant(zero ? 0 : consts[nextConst].getUConst(), specConstant);
break;
case glslang::EbtFloat:
- scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst());
+ scalar = builder.makeFloatConstant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant);
break;
case glslang::EbtDouble:
- scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst());
+ scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant);
break;
case glslang::EbtBool:
- scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst());
+ scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
break;
default:
- spv::MissingFunctionality("constant scalar type");
+ assert(0);
break;
}
++nextConst;
@@ -3180,7 +3282,7 @@
{
const int bufSize = 100;
char buf[bufSize];
- snprintf(buf, bufSize, "%d, Revision %d", spv::Version, spv::Revision);
+ snprintf(buf, bufSize, "0x%08x, Revision %d", spv::Version, spv::Revision);
version = buf;
}
diff --git a/SPIRV/SPVRemapper.cpp b/SPIRV/SPVRemapper.cpp
index 0f303e3..9beba21 100755
--- a/SPIRV/SPVRemapper.cpp
+++ b/SPIRV/SPVRemapper.cpp
@@ -446,7 +446,6 @@
idFn(asId(word++));
break;
- case spv::OperandOptionalId:
case spv::OperandVariableIds:
for (unsigned i = 0; i < numOperands; ++i)
idFn(asId(word++));
diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp
index dba9c4c..a46c924 100755
--- a/SPIRV/SpvBuilder.cpp
+++ b/SPIRV/SpvBuilder.cpp
@@ -55,14 +55,12 @@
namespace spv {
-const int SpvBuilderMagic = 0xBB;
-
-Builder::Builder(unsigned int userNumber) :
+Builder::Builder(unsigned int magicNumber) :
source(SourceLanguageUnknown),
sourceVersion(0),
addressModel(AddressingModelLogical),
memoryModel(MemoryModelGLSL450),
- builderNumber(userNumber << 16 | SpvBuilderMagic),
+ builderNumber(magicNumber),
buildPoint(0),
uniqueId(0),
mainFunction(0)
@@ -112,6 +110,20 @@
return type->getResultId();
}
+Id Builder::makeSamplerType()
+{
+ Instruction* type;
+ if (groupedTypes[OpTypeSampler].size() == 0) {
+ type = new Instruction(getUniqueId(), NoType, OpTypeSampler);
+ groupedTypes[OpTypeSampler].push_back(type);
+ constantsTypesGlobals.push_back(type);
+ module.mapInstruction(type);
+ } else
+ type = groupedTypes[OpTypeSampler].back();
+
+ return type->getResultId();
+}
+
Id Builder::makePointer(StorageClass storageClass, Id pointee)
{
// try to find it
@@ -176,8 +188,15 @@
return type->getResultId();
}
+// Make a struct without checking for duplication.
+// See makeStructResultType() for non-decorated structs
+// needed as the result of some instructions, which does
+// check for duplicates.
Id Builder::makeStructType(std::vector<Id>& members, const char* name)
{
+ // Don't look for previous one, because in the general case,
+ // structs can be duplicated except for decorations.
+
// not found, make it
Instruction* type = new Instruction(getUniqueId(), NoType, OpTypeStruct);
for (int op = 0; op < (int)members.size(); ++op)
@@ -190,6 +209,30 @@
return type->getResultId();
}
+// Make a struct for the simple results of several instructions,
+// checking for duplication.
+Id Builder::makeStructResultType(Id type0, Id type1)
+{
+ // try to find it
+ Instruction* type;
+ for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) {
+ type = groupedTypes[OpTypeStruct][t];
+ if (type->getNumOperands() != 2)
+ continue;
+ if (type->getIdOperand(0) != type0 ||
+ type->getIdOperand(1) != type1)
+ continue;
+ return type->getResultId();
+ }
+
+ // not found, make it
+ std::vector<spv::Id> members;
+ members.push_back(type0);
+ members.push_back(type1);
+
+ return makeStructType(members, "ResType");
+}
+
Id Builder::makeVectorType(Id component, int size)
{
// try to find it
@@ -387,7 +430,7 @@
case OpTypePointer:
return getMostBasicTypeClass(instr->getIdOperand(1));
default:
- MissingFunctionality("getMostBasicTypeClass");
+ assert(0);
return OpTypeFloat;
}
}
@@ -406,7 +449,7 @@
case OpTypeMatrix:
return instr->getImmediateOperand(1);
default:
- MissingFunctionality("getNumTypeComponents on non bool/int/float/vector/matrix");
+ assert(0);
return 1;
}
}
@@ -434,7 +477,7 @@
case OpTypePointer:
return getScalarTypeId(getContainedTypeId(typeId));
default:
- MissingFunctionality("getScalarTypeId");
+ assert(0);
return NoResult;
}
}
@@ -457,7 +500,7 @@
case OpTypeStruct:
return instr->getIdOperand(member);
default:
- MissingFunctionality("getContainedTypeId");
+ assert(0);
return NoResult;
}
}
@@ -470,12 +513,12 @@
// See if a scalar constant of this type has already been created, so it
// can be reused rather than duplicated. (Required by the specification).
-Id Builder::findScalarConstant(Op typeClass, Id typeId, unsigned value) const
+Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const
{
Instruction* constant;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
constant = groupedConstants[typeClass][i];
- if (constant->getNumOperands() == 1 &&
+ if (constant->getOpCode() == opcode &&
constant->getTypeId() == typeId &&
constant->getImmediateOperand(0) == value)
return constant->getResultId();
@@ -485,12 +528,12 @@
}
// Version of findScalarConstant (see above) for scalars that take two operands (e.g. a 'double').
-Id Builder::findScalarConstant(Op typeClass, Id typeId, unsigned v1, unsigned v2) const
+Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
{
Instruction* constant;
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
constant = groupedConstants[typeClass][i];
- if (constant->getNumOperands() == 2 &&
+ if (constant->getOpCode() == opcode &&
constant->getTypeId() == typeId &&
constant->getImmediateOperand(0) == v1 &&
constant->getImmediateOperand(1) == v2)
@@ -524,18 +567,17 @@
}
}
-Id Builder::makeBoolConstant(bool b)
+Id Builder::makeBoolConstant(bool b, bool specConstant)
{
Id typeId = makeBoolType();
Instruction* constant;
+ Op opcode = specConstant ? (b ? OpSpecConstantTrue : OpSpecConstantFalse) : (b ? OpConstantTrue : OpConstantFalse);
// See if we already made it
Id existing = 0;
for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) {
constant = groupedConstants[OpTypeBool][i];
- if (constant->getTypeId() == typeId &&
- (b ? (constant->getOpCode() == OpConstantTrue) :
- (constant->getOpCode() == OpConstantFalse)))
+ if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
existing = constant->getResultId();
}
@@ -543,7 +585,7 @@
return existing;
// Make it
- Instruction* c = new Instruction(getUniqueId(), typeId, b ? OpConstantTrue : OpConstantFalse);
+ Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
constantsTypesGlobals.push_back(c);
groupedConstants[OpTypeBool].push_back(c);
module.mapInstruction(c);
@@ -551,13 +593,14 @@
return c->getResultId();
}
-Id Builder::makeIntConstant(Id typeId, unsigned value)
+Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
{
- Id existing = findScalarConstant(OpTypeInt, typeId, value);
+ Op opcode = specConstant ? OpSpecConstant : OpConstant;
+ Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);
if (existing)
return existing;
- Instruction* c = new Instruction(getUniqueId(), typeId, OpConstant);
+ Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
c->addImmediateOperand(value);
constantsTypesGlobals.push_back(c);
groupedConstants[OpTypeInt].push_back(c);
@@ -566,15 +609,16 @@
return c->getResultId();
}
-Id Builder::makeFloatConstant(float f)
+Id Builder::makeFloatConstant(float f, bool specConstant)
{
+ Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(32);
unsigned value = *(unsigned int*)&f;
- Id existing = findScalarConstant(OpTypeFloat, typeId, value);
+ Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
if (existing)
return existing;
- Instruction* c = new Instruction(getUniqueId(), typeId, OpConstant);
+ Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
c->addImmediateOperand(value);
constantsTypesGlobals.push_back(c);
groupedConstants[OpTypeFloat].push_back(c);
@@ -583,17 +627,18 @@
return c->getResultId();
}
-Id Builder::makeDoubleConstant(double d)
+Id Builder::makeDoubleConstant(double d, bool specConstant)
{
+ Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(64);
unsigned long long value = *(unsigned long long*)&d;
unsigned op1 = value & 0xFFFFFFFF;
unsigned op2 = value >> 32;
- Id existing = findScalarConstant(OpTypeFloat, typeId, op1, op2);
+ Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);
if (existing)
return existing;
- Instruction* c = new Instruction(getUniqueId(), typeId, OpConstant);
+ Instruction* c = new Instruction(getUniqueId(), typeId, opcode);
c->addImmediateOperand(op1);
c->addImmediateOperand(op2);
constantsTypesGlobals.push_back(c);
@@ -644,7 +689,7 @@
case OpTypeMatrix:
break;
default:
- MissingFunctionality("Constant composite type in Builder");
+ assert(0);
return makeFloatConstant(0.0);
}
@@ -662,7 +707,7 @@
return c->getResultId();
}
-void Builder::addEntryPoint(ExecutionModel model, Function* function, const char* name)
+Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, const char* name)
{
Instruction* entryPoint = new Instruction(OpEntryPoint);
entryPoint->addImmediateOperand(model);
@@ -670,6 +715,8 @@
entryPoint->addStringOperand(name);
entryPoints.push_back(entryPoint);
+
+ return entryPoint;
}
// Currently relying on the fact that all 'value' of interest are small non-negative values.
@@ -720,6 +767,8 @@
void Builder::addDecoration(Id id, Decoration decoration, int num)
{
+ if (decoration == (spv::Decoration)spv::BadValue)
+ return;
Instruction* dec = new Instruction(OpDecorate);
dec->addIdOperand(id);
dec->addImmediateOperand(decoration);
@@ -833,25 +882,14 @@
inst->addImmediateOperand(storageClass);
switch (storageClass) {
- case StorageClassUniformConstant:
- case StorageClassUniform:
- case StorageClassInput:
- case StorageClassOutput:
- case StorageClassWorkgroupLocal:
- case StorageClassPrivateGlobal:
- case StorageClassWorkgroupGlobal:
- case StorageClassAtomicCounter:
- constantsTypesGlobals.push_back(inst);
- module.mapInstruction(inst);
- break;
-
case StorageClassFunction:
// Validation rules require the declaration in the entry block
buildPoint->getParent().addLocalVariable(inst);
break;
default:
- MissingFunctionality("storage class in createVariable");
+ constantsTypesGlobals.push_back(inst);
+ module.mapInstruction(inst);
break;
}
@@ -1175,7 +1213,7 @@
// Accept all parameters needed to create a texture instruction.
// Create the correct instruction based on the inputs, and make the call.
-Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, const TextureParameters& parameters)
+Id Builder::createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, bool gather, const TextureParameters& parameters)
{
static const int maxTextureArgs = 10;
Id texArgs[maxTextureArgs] = {};
@@ -1189,6 +1227,8 @@
texArgs[numArgs++] = parameters.coords;
if (parameters.Dref)
texArgs[numArgs++] = parameters.Dref;
+ if (parameters.comp)
+ texArgs[numArgs++] = parameters.comp;
//
// Set up the optional arguments
@@ -1238,6 +1278,11 @@
opCode = OpImageSampleImplicitLod;
if (fetch) {
opCode = OpImageFetch;
+ } else if (gather) {
+ if (parameters.Dref)
+ opCode = OpImageDrefGather;
+ else
+ opCode = OpImageGather;
} else if (xplicit) {
if (parameters.Dref) {
if (proj)
@@ -1281,6 +1326,7 @@
}
}
+ // Build the SPIR-V instruction
Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode);
for (int op = 0; op < optArgNum; ++op)
textureInst->addIdOperand(texArgs[op]);
@@ -1324,8 +1370,12 @@
case Dim3D:
numComponents = 3;
break;
+ case DimSubpassData:
+ MissingFunctionality("input-attachment dim");
+ break;
+
default:
- MissingFunctionality("texture query dimensionality");
+ assert(0);
break;
}
if (isArrayedImageType(getImageType(parameters.sampler)))
@@ -1345,7 +1395,8 @@
resultType = makeIntType(32);
break;
default:
- MissingFunctionality("Texture query op code");
+ assert(0);
+ break;
}
Instruction* query = new Instruction(getUniqueId(), resultType, opCode);
@@ -1360,57 +1411,6 @@
}
// Comments in header
-//Id Builder::createSamplePositionCall(Decoration precision, Id returnType, Id sampleIdx)
-//{
-// // Return type is only flexible type
-// Function* opCode = (fSamplePosition, returnType);
-//
-// Instruction* instr = (opCode, sampleIdx);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-
-// Comments in header
-//Id Builder::createBitFieldExtractCall(Decoration precision, Id id, Id offset, Id bits, bool isSigned)
-//{
-// Op opCode = isSigned ? sBitFieldExtract
-// : uBitFieldExtract;
-//
-// if (isScalar(offset) == false || isScalar(bits) == false)
-// MissingFunctionality("bitFieldExtract operand types");
-//
-// // Dest and value are matching flexible types
-// Function* opCode = (opCode, id->getType(), id->getType());
-//
-// assert(opCode);
-//
-// Instruction* instr = (opCode, id, offset, bits);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-
-// Comments in header
-//Id Builder::createBitFieldInsertCall(Decoration precision, Id base, Id insert, Id offset, Id bits)
-//{
-// Op opCode = bitFieldInsert;
-//
-// if (isScalar(offset) == false || isScalar(bits) == false)
-// MissingFunctionality("bitFieldInsert operand types");
-//
-// // Dest, base, and insert are matching flexible types
-// Function* opCode = (opCode, base->getType(), base->getType(), base->getType());
-//
-// assert(opCode);
-//
-// Instruction* instr = (opCode, base, insert, offset, bits);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-
-// Comments in header
Id Builder::createCompare(Decoration precision, Id value1, Id value2, bool equal)
{
Id boolType = makeBoolType();
@@ -1488,115 +1488,6 @@
//return result;
}
-// Comments in header
-//Id Builder::createOperation(Decoration precision, Op opCode, Id operand)
-//{
-// Op* opCode = 0;
-//
-// // Handle special return types here. Things that don't have same result type as parameter
-// switch (opCode) {
-// case fIsNan:
-// case fIsInf:
-// break;
-// case fFloatBitsToInt:
-// break;
-// case fIntBitsTofloat:
-// break;
-// case fPackSnorm2x16:
-// case fPackUnorm2x16:
-// case fPackHalf2x16:
-// break;
-// case fUnpackUnorm2x16:
-// case fUnpackSnorm2x16:
-// case fUnpackHalf2x16:
-// break;
-//
-// case fFrexp:
-// case fLdexp:
-// case fPackUnorm4x8:
-// case fPackSnorm4x8:
-// case fUnpackUnorm4x8:
-// case fUnpackSnorm4x8:
-// case fPackDouble2x32:
-// case fUnpackDouble2x32:
-// break;
-// case fLength:
-// // scalar result type
-// break;
-// case any:
-// case all:
-// // fixed result type
-// break;
-// case fModF:
-// // modf() will return a struct that the caller must decode
-// break;
-// default:
-// // Unary operations that have operand and dest with same flexible type
-// break;
-// }
-//
-// assert(opCode);
-//
-// Instruction* instr = (opCode, operand);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-//
-//// Comments in header
-//Id Builder::createOperation(Decoration precision, Op opCode, Id operand0, Id operand1)
-//{
-// Function* opCode = 0;
-//
-// // Handle special return types here. Things that don't have same result type as parameter
-// switch (opCode) {
-// case fDistance:
-// case fDot2:
-// case fDot3:
-// case fDot4:
-// // scalar result type
-// break;
-// case fStep:
-// // first argument can be scalar, return and second argument match
-// break;
-// case fSmoothStep:
-// // first argument can be scalar, return and second argument match
-// break;
-// default:
-// // Binary operations that have operand and dest with same flexible type
-// break;
-// }
-//
-// assert(opCode);
-//
-// Instruction* instr = (opCode, operand0, operand1);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-//
-//Id Builder::createOperation(Decoration precision, Op opCode, Id operand0, Id operand1, Id operand2)
-//{
-// Function* opCode;
-//
-// // Handle special return types here. Things that don't have same result type as parameter
-// switch (opCode) {
-// case fSmoothStep:
-// // first argument can be scalar, return and second argument match
-// break;
-// default:
-// // Use operand0 type as result type
-// break;
-// }
-//
-// assert(opCode);
-//
-// Instruction* instr = (opCode, operand0, operand1, operand2);
-// setPrecision(instr, precision);
-//
-// return instr;
-//}
-
// OpCompositeConstruct
Id Builder::createCompositeConstruct(Id typeId, std::vector<Id>& constituents)
{
@@ -1625,11 +1516,8 @@
Id scalarTypeId = getScalarTypeId(resultTypeId);
std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct
for (unsigned int i = 0; i < sources.size(); ++i) {
- if (isAggregate(sources[i]))
- MissingFunctionality("aggregate in vector constructor");
-
+ assert(! isAggregate(sources[i]));
unsigned int sourceSize = getNumComponents(sources[i]);
-
unsigned int sourcesToUse = sourceSize;
if (sourcesToUse + targetComponent > numTargetComponents)
sourcesToUse = numTargetComponents - targetComponent;
@@ -1790,7 +1678,7 @@
// Go back to the headerBlock and make the flow control split
builder.setBuildPoint(headerBlock);
- builder.createMerge(OpSelectionMerge, mergeBlock, SelectionControlMaskNone);
+ builder.createSelectionMerge(mergeBlock, SelectionControlMaskNone);
if (elseBlock)
builder.createConditionalBranch(condition, thenBlock, elseBlock);
else
@@ -1814,7 +1702,7 @@
Block* mergeBlock = new Block(getUniqueId(), function);
// make and insert the switch's selection-merge instruction
- createMerge(OpSelectionMerge, mergeBlock, SelectionControlMaskNone);
+ createSelectionMerge(mergeBlock, SelectionControlMaskNone);
// make the switch instruction
Instruction* switchInst = new Instruction(NoResult, NoType, OpSwitch);
@@ -1898,7 +1786,7 @@
getBuildPoint()->addInstruction(loop.isFirstIteration);
// Mark the end of the structured loop. This must exist in the loop header block.
- createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone);
+ createLoopMerge(loop.merge, loop.header, LoopControlMaskNone);
// Generate code to see if this is the first iteration of the loop.
// It needs to be in its own block, since the loop merge and
@@ -1912,7 +1800,7 @@
// Control flow after this "if" normally reconverges at the loop body.
// However, the loop test has a "break branch" out of this selection
// construct because it can transfer control to the loop merge block.
- createMerge(OpSelectionMerge, loop.body, SelectionControlMaskNone);
+ createSelectionMerge(loop.body, SelectionControlMaskNone);
Block* loopTest = new Block(getUniqueId(), *loop.function);
createConditionalBranch(loop.isFirstIteration->getResultId(), loop.body, loopTest);
@@ -1930,7 +1818,7 @@
// the body, then this is a loop merge. Otherwise the loop merge
// has already been generated and this is a conditional merge.
if (loop.testFirst) {
- createMerge(OpLoopMerge, loop.merge, LoopControlMaskNone);
+ createLoopMerge(loop.merge, loop.header, LoopControlMaskNone);
// Branching to the "body" block will keep control inside
// the loop.
createConditionalBranch(condition, loop.body, loop.merge);
@@ -1943,7 +1831,7 @@
// of a merge instruction, and a block can't be the target of more
// than one merge instruction, we need to make an intermediate block.
Block* stayInLoopBlock = new Block(getUniqueId(), *loop.function);
- createMerge(OpSelectionMerge, stayInLoopBlock, SelectionControlMaskNone);
+ createSelectionMerge(stayInLoopBlock, SelectionControlMaskNone);
// This is the loop test.
createConditionalBranch(condition, stayInLoopBlock, loop.merge);
@@ -2047,12 +1935,13 @@
{
assert(accessChain.isRValue == false);
+ transferAccessChainSwizzle(true);
Id base = collapseAccessChain();
if (accessChain.swizzle.size() && accessChain.component != NoResult)
MissingFunctionality("simultaneous l-value swizzle and dynamic component selection");
- // If swizzle exists, it is out-of-order or not full, we must load the target vector,
+ // If swizzle still exists, it is out-of-order or not full, we must load the target vector,
// extract and insert elements to perform writeMask and/or swizzle.
Id source = NoResult;
if (accessChain.swizzle.size()) {
@@ -2078,8 +1967,9 @@
Id id;
if (accessChain.isRValue) {
+ // transfer access chain, but keep it static, so we can stay in registers
+ transferAccessChainSwizzle(false);
if (accessChain.indexChain.size() > 0) {
- mergeAccessChainSwizzle(); // TODO: optimization: look at applying this optimization more widely
Id swizzleBase = accessChain.preSwizzleBaseType != NoType ? accessChain.preSwizzleBaseType : resultType;
// if all the accesses are constants, we can use OpCompositeExtract
@@ -2113,6 +2003,7 @@
} else
id = accessChain.base;
} else {
+ transferAccessChainSwizzle(true);
// load through the access chain
id = createLoad(collapseAccessChain());
}
@@ -2142,6 +2033,7 @@
{
assert(accessChain.isRValue == false);
+ transferAccessChainSwizzle(true);
Id lvalue = collapseAccessChain();
// If swizzle exists, it is out-of-order or not full, we must load the target vector,
@@ -2162,7 +2054,26 @@
out.push_back(uniqueId + 1);
out.push_back(0);
- // First instructions, some created on the spot here:
+ // Capabilities
+ for (auto cap : capabilities) {
+ Instruction capInst(0, 0, OpCapability);
+ capInst.addImmediateOperand(cap);
+ capInst.dump(out);
+ }
+
+ // TBD: OpExtension ...
+
+ dumpInstructions(out, imports);
+ Instruction memInst(0, 0, OpMemoryModel);
+ memInst.addImmediateOperand(addressModel);
+ memInst.addImmediateOperand(memoryModel);
+ memInst.dump(out);
+
+ // Instructions saved up while building:
+ dumpInstructions(out, entryPoints);
+ dumpInstructions(out, executionModes);
+
+ // Debug instructions
if (source != SourceLanguageUnknown) {
Instruction sourceInst(0, 0, OpSource);
sourceInst.addImmediateOperand(source);
@@ -2174,28 +2085,12 @@
extInst.addStringOperand(extensions[e]);
extInst.dump(out);
}
-
- // TBD: OpExtension ...
-
- // Capabilities
- for (auto cap : capabilities) {
- Instruction capInst(0, 0, OpCapability);
- capInst.addImmediateOperand(cap);
- capInst.dump(out);
- }
-
- dumpInstructions(out, imports);
- Instruction memInst(0, 0, OpMemoryModel);
- memInst.addImmediateOperand(addressModel);
- memInst.addImmediateOperand(memoryModel);
- memInst.dump(out);
-
- // Instructions saved up while building:
- dumpInstructions(out, entryPoints);
- dumpInstructions(out, executionModes);
dumpInstructions(out, names);
dumpInstructions(out, lines);
+
+ // Annotation instructions
dumpInstructions(out, decorations);
+
dumpInstructions(out, constantsTypesGlobals);
dumpInstructions(out, externals);
@@ -2207,10 +2102,13 @@
// Protected methods.
//
+// Turn the described access chain in 'accessChain' into an instruction
+// computing its address. This *cannot* include complex swizzles, which must
+// be handled after this is called, but it does include swizzles that select
+// an individual element, as a single address of a scalar type can be
+// computed by an OpAccessChain instruction.
Id Builder::collapseAccessChain()
{
- // TODO: bring in an individual component swizzle here, so that a pointer
- // all the way to the component level can be created.
assert(accessChain.isRValue == false);
if (accessChain.indexChain.size() > 0) {
@@ -2222,9 +2120,12 @@
return accessChain.instr;
} else
return accessChain.base;
+
+ // note that non-trivial swizzling is left pending...
}
-// clear out swizzle if it is redundant
+// clear out swizzle if it is redundant, that is reselecting the same components
+// that would be present without the swizzle.
void Builder::simplifyAccessChainSwizzle()
{
// If the swizzle has fewer components than the vector, it is subsetting, and must stay
@@ -2244,29 +2145,45 @@
accessChain.preSwizzleBaseType = NoType;
}
-// clear out swizzle if it can become part of the indexes
-void Builder::mergeAccessChainSwizzle()
+// To the extent any swizzling can become part of the chain
+// of accesses instead of a post operation, make it so.
+// If 'dynamic' is true, include transfering a non-static component index,
+// otherwise, only transfer static indexes.
+//
+// Also, Boolean vectors are likely to be special. While
+// for external storage, they should only be integer types,
+// function-local bool vectors could use sub-word indexing,
+// so keep that as a separate Insert/Extract on a loaded vector.
+void Builder::transferAccessChainSwizzle(bool dynamic)
{
- // is there even a chance of doing something? Need a single-component swizzle
- if ((accessChain.swizzle.size() > 1) ||
- (accessChain.swizzle.size() == 0 && accessChain.component == NoResult))
+ // too complex?
+ if (accessChain.swizzle.size() > 1)
return;
- // TODO: optimization: remove this, but for now confine this to non-dynamic accesses
- // (the above test is correct when this is removed.)
- if (accessChain.component != NoResult)
+ // non existent?
+ if (accessChain.swizzle.size() == 0 && accessChain.component == NoResult)
return;
- // move the swizzle over to the indexes
- if (accessChain.swizzle.size() == 1)
+ // single component...
+
+ // skip doing it for Boolean vectors
+ if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
+ return;
+
+ if (accessChain.swizzle.size() == 1) {
+ // handle static component
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
- else
+ accessChain.swizzle.clear();
+ // note, the only valid remaining dynamic access would be to this one
+ // component, so don't bother even looking at accessChain.component
+ accessChain.preSwizzleBaseType = NoType;
+ accessChain.component = NoResult;
+ } else if (dynamic && accessChain.component != NoResult) {
+ // handle dynamic component
accessChain.indexChain.push_back(accessChain.component);
-
- // now there is no need to track this swizzle
- accessChain.component = NoResult;
- accessChain.preSwizzleBaseType = NoType;
- accessChain.swizzle.clear();
+ accessChain.preSwizzleBaseType = NoType;
+ accessChain.component = NoResult;
+ }
}
// Utility method for creating a new block and setting the insert point to
@@ -2292,14 +2209,23 @@
block->addPredecessor(buildPoint);
}
-void Builder::createMerge(Op mergeCode, Block* mergeBlock, unsigned int control)
+void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
{
- Instruction* merge = new Instruction(mergeCode);
+ Instruction* merge = new Instruction(OpSelectionMerge);
merge->addIdOperand(mergeBlock->getId());
merge->addImmediateOperand(control);
buildPoint->addInstruction(merge);
}
+void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control)
+{
+ Instruction* merge = new Instruction(OpLoopMerge);
+ merge->addIdOperand(mergeBlock->getId());
+ merge->addIdOperand(continueBlock->getId());
+ merge->addImmediateOperand(control);
+ buildPoint->addInstruction(merge);
+}
+
void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock)
{
Instruction* branch = new Instruction(OpBranchConditional);
diff --git a/SPIRV/SpvBuilder.h b/SPIRV/SpvBuilder.h
index 3bc8db2..5750b00 100755
--- a/SPIRV/SpvBuilder.h
+++ b/SPIRV/SpvBuilder.h
@@ -99,12 +99,14 @@
Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width);
Id makeStructType(std::vector<Id>& members, const char*);
+ Id makeStructResultType(Id type0, Id type1);
Id makeVectorType(Id component, int size);
Id makeMatrixType(Id component, int cols, int rows);
Id makeArrayType(Id element, unsigned size);
Id makeRuntimeArray(Id element);
Id makeFunctionType(Id returnType, std::vector<Id>& paramTypes);
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
+ Id makeSamplerType();
Id makeSampledImageType(Id imageType);
// For querying about types.
@@ -118,12 +120,14 @@
Id getScalarTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId) const;
Id getContainedTypeId(Id typeId, int) const;
+ StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
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 isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
+ bool isBoolType(Id typeId) const { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
@@ -140,6 +144,7 @@
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
+ StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
int getTypeNumColumns(Id typeId) const
{
@@ -172,18 +177,17 @@
}
// For making new constants (will return old constant if the requested one was already made).
- Id makeBoolConstant(bool b);
- Id makeIntConstant(Id typeId, unsigned value);
- Id makeIntConstant(int i) { return makeIntConstant(makeIntType(32), (unsigned)i); }
- Id makeUintConstant(unsigned u) { return makeIntConstant(makeUintType(32), u); }
- Id makeFloatConstant(float f);
- Id makeDoubleConstant(double d);
+ Id makeBoolConstant(bool b, bool specConstant = false);
+ Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
+ Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
+ Id makeFloatConstant(float f, bool specConstant = false);
+ Id makeDoubleConstant(double d, bool specConstant = false);
// Turn the array of constants into a proper spv constant of the requested type.
Id makeCompositeConstant(Id type, std::vector<Id>& comps);
// Methods for adding information outside the CFG.
- void addEntryPoint(ExecutionModel, Function*, const char* name);
+ Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
void addName(Id, const char* name);
void addMemberName(Id, int member, const char* name);
@@ -296,10 +300,11 @@
Id gradX;
Id gradY;
Id sample;
+ Id comp;
};
// Select the correct texture operation based on all inputs, and emit the correct instruction
- Id createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, const TextureParameters&);
+ Id createTextureCall(Decoration precision, Id resultType, bool fetch, bool proj, bool gather, const TextureParameters&);
// Emit the OpTextureQuery* instruction that was passed in.
// Figure out the right return value and type, and return it.
@@ -426,13 +431,13 @@
//
struct AccessChain {
- Id base; // for l-values, pointer to the base object, for r-values, the base object
+ Id base; // for l-values, pointer to the base object, for r-values, the base object
std::vector<Id> indexChain;
- Id instr; // the instruction that generates this access chain
- std::vector<unsigned> swizzle;
- Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle
- Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
- bool isRValue;
+ Id instr; // cache the instruction that generates this access chain
+ std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
+ Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
+ Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
+ bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
};
//
@@ -490,15 +495,17 @@
void dump(std::vector<unsigned int>&) const;
protected:
- Id findScalarConstant(Op typeClass, Id typeId, unsigned value) const;
- Id findScalarConstant(Op typeClass, Id typeId, unsigned v1, unsigned v2) const;
+ Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
+ Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const;
+ Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const;
Id findCompositeConstant(Op typeClass, std::vector<Id>& comps) const;
Id collapseAccessChain();
+ void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle();
- void mergeAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createBranch(Block* block);
- void createMerge(Op, Block*, unsigned int control);
+ void createSelectionMerge(Block* mergeBlock, unsigned int control);
+ void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
diff --git a/SPIRV/disassemble.cpp b/SPIRV/disassemble.cpp
index 9df69e9..8662f03 100755
--- a/SPIRV/disassemble.cpp
+++ b/SPIRV/disassemble.cpp
@@ -48,15 +48,17 @@
#include <sstream>
#include <cstring>
+namespace spv {
+ // Include C-based headers that don't have a namespace
+ #include "SPIRV/GLSL.std.450.h"
+}
+const char* GlslStd450DebugNames[spv::GLSLstd450Count];
+
#include "disassemble.h"
#include "doc.h"
namespace spv {
-#include "GLSL.std.450.h"
-
-const char* GlslStd450DebugNames[spv::GLSLstd450Count];
-
void Kill(std::ostream& out, const char* message)
{
out << std::endl << "Disassembly failed: " << message << std::endl;
@@ -92,7 +94,7 @@
void outputMask(OperandClass operandClass, unsigned mask);
void disassembleImmediates(int numOperands);
void disassembleIds(int numOperands);
- void disassembleString();
+ int disassembleString();
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
// Data
@@ -128,10 +130,10 @@
}
// Version
- out << "// Module Version " << stream[word++] << std::endl;
+ out << "// Module Version " << std::hex << stream[word++] << std::endl;
// Generator's magic number
- out << "// Generated by (magic number): " << std::setbase(16) << stream[word++] << std::setbase(10) << std::endl;
+ out << "// Generated by (magic number): " << std::hex << stream[word++] << std::dec << std::endl;
// Result <id> bound
bound = stream[word++];
@@ -280,15 +282,18 @@
}
}
-void SpirvStream::disassembleString()
+// return the number of operands consumed by the string
+int SpirvStream::disassembleString()
{
+ int startWord = word;
+
out << " \"";
- char* wordString;
+ const char* wordString;
bool done = false;
do {
unsigned int content = stream[word];
- wordString = (char*)&content;
+ wordString = (const char*)&content;
for (int charCount = 0; charCount < 4; ++charCount) {
if (*wordString == 0) {
done = true;
@@ -300,6 +305,8 @@
} while (! done);
out << "\"";
+
+ return word - startWord;
}
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
@@ -389,15 +396,15 @@
case OperandScope:
case OperandMemorySemantics:
disassembleIds(1);
+ --numOperands;
// Get names for printing "(XXX)" for readability, *after* this id
if (opCode == OpName)
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
break;
- case OperandOptionalId:
case OperandVariableIds:
disassembleIds(numOperands);
return;
- case OperandOptionalImage:
+ case OperandImageOperands:
outputMask(OperandImageOperands, stream[word++]);
--numOperands;
disassembleIds(numOperands);
@@ -440,6 +447,7 @@
return;
case OperandLiteralNumber:
disassembleImmediates(1);
+ --numOperands;
if (opCode == OpExtInst) {
ExtInstSet extInstSet = GLSL450Inst;
if (0 == memcmp("OpenCL", (const char*)(idDescriptor[stream[word-2]].c_str()), 6)) {
@@ -447,15 +455,16 @@
}
unsigned entrypoint = stream[word - 1];
if (extInstSet == GLSL450Inst) {
- if (entrypoint < spv::GLSLstd450Count) {
+ if (entrypoint < GLSLstd450Count) {
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
}
}
}
break;
+ case OperandOptionalLiteralString:
case OperandLiteralString:
- disassembleString();
- return;
+ numOperands -= disassembleString();
+ break;
default:
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
@@ -463,10 +472,9 @@
outputMask(operandClass, stream[word++]);
else
out << OperandClassParams[operandClass].getName(stream[word++]);
-
+ --numOperands;
break;
}
- --numOperands;
}
return;
@@ -508,9 +516,9 @@
names[GLSLstd450Exp2] = "Exp2";
names[GLSLstd450Log2] = "Log2";
names[GLSLstd450Sqrt] = "Sqrt";
- names[GLSLstd450InverseSqrt] = "Inversesqrt";
+ names[GLSLstd450InverseSqrt] = "InverseSqrt";
names[GLSLstd450Determinant] = "Determinant";
- names[GLSLstd450MatrixInverse] = "Inverse";
+ names[GLSLstd450MatrixInverse] = "MatrixInverse";
names[GLSLstd450Modf] = "Modf";
names[GLSLstd450ModfStruct] = "ModfStruct";
names[GLSLstd450FMin] = "FMin";
@@ -522,9 +530,10 @@
names[GLSLstd450FClamp] = "FClamp";
names[GLSLstd450SClamp] = "SClamp";
names[GLSLstd450UClamp] = "UClamp";
- names[GLSLstd450Mix] = "Mix";
+ names[GLSLstd450FMix] = "FMix";
+ names[GLSLstd450IMix] = "IMix";
names[GLSLstd450Step] = "Step";
- names[GLSLstd450SmoothStep] = "Smoothstep";
+ names[GLSLstd450SmoothStep] = "SmoothStep";
names[GLSLstd450Fma] = "Fma";
names[GLSLstd450Frexp] = "Frexp";
names[GLSLstd450FrexpStruct] = "FrexpStruct";
@@ -545,15 +554,12 @@
names[GLSLstd450Distance] = "Distance";
names[GLSLstd450Cross] = "Cross";
names[GLSLstd450Normalize] = "Normalize";
- names[GLSLstd450FaceForward] = "Faceforward";
+ names[GLSLstd450FaceForward] = "FaceForward";
names[GLSLstd450Reflect] = "Reflect";
names[GLSLstd450Refract] = "Refract";
- names[GLSLstd450AddCarry] = "UaddCarry";
- names[GLSLstd450SubBorrow] = "UsubBorrow";
- names[GLSLstd450MulExtended] = "UmulExtended";
- names[GLSLstd450FindILSB] = "FindILsb";
- names[GLSLstd450FindSMSB] = "FindSMsb";
- names[GLSLstd450FindUMSB] = "FindUMsb";
+ names[GLSLstd450FindILsb] = "FindILsb";
+ names[GLSLstd450FindSMsb] = "FindSMsb";
+ names[GLSLstd450FindUMsb] = "FindUMsb";
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index ff0d780..64a55f9 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -64,7 +64,7 @@
// (for non-sparse mask enums, this is the number of enumurants)
//
-const int SourceLanguageCeiling = 4;
+const int SourceLanguageCeiling = 5;
const char* SourceString(int source)
{
@@ -72,7 +72,8 @@
case 0: return "Unknown";
case 1: return "ESSL";
case 2: return "GLSL";
- case 3: return "OpenCL";
+ case 3: return "OpenCL_C";
+ case 4: return "OpenCL_CPP";
case SourceLanguageCeiling:
default: return "Bad";
@@ -125,7 +126,7 @@
}
}
-const int ExecutionModeCeiling = 32;
+const int ExecutionModeCeiling = 33;
const char* ExecutionModeString(int mode)
{
@@ -143,7 +144,7 @@
case 10: return "PointMode";
case 11: return "Xfb";
case 12: return "DepthReplacing";
- case 13: return "DepthAny";
+ case 13: return "Bad";
case 14: return "DepthGreater";
case 15: return "DepthLess";
case 16: return "DepthUnchanged";
@@ -152,16 +153,17 @@
case 19: return "InputPoints";
case 20: return "InputLines";
case 21: return "InputLinesAdjacency";
- case 22: return "InputTriangles";
+ case 22: return "Triangles";
case 23: return "InputTrianglesAdjacency";
- case 24: return "InputQuads";
- case 25: return "InputIsolines";
+ case 24: return "Quads";
+ case 25: return "Isolines";
case 26: return "OutputVertices";
case 27: return "OutputPoints";
case 28: return "OutputLineStrip";
case 29: return "OutputTriangleStrip";
case 30: return "VecTypeHint";
case 31: return "ContractionOff";
+ case 32: return "Bad";
case ExecutionModeCeiling:
default: return "Bad";
@@ -177,12 +179,12 @@
case 1: return "Input";
case 2: return "Uniform";
case 3: return "Output";
- case 4: return "WorkgroupLocal";
- case 5: return "WorkgroupGlobal";
- case 6: return "PrivateGlobal";
+ case 4: return "Workgroup";
+ case 5: return "CrossWorkgroup";
+ case 6: return "Private";
case 7: return "Function";
case 8: return "Generic";
- case 9: return "Bad";
+ case 9: return "PushConstant";
case 10: return "AtomicCounter";
case 11: return "Image";
@@ -191,7 +193,7 @@
}
}
-const int DecorationCeiling = 42;
+const int DecorationCeiling = 45;
const char* DecorationString(int decoration)
{
@@ -208,8 +210,8 @@
case 9: return "GLSLPacked";
case 10: return "CPacked";
case 11: return "BuiltIn";
- case 12: return "Smooth";
- case 13: return "Noperspective";
+ case 12: return "Bad";
+ case 13: return "NoPerspective";
case 14: return "Flat";
case 15: return "Patch";
case 16: return "Centroid";
@@ -220,10 +222,10 @@
case 21: return "Volatile";
case 22: return "Constant";
case 23: return "Coherent";
- case 24: return "Nonwritable";
- case 25: return "Nonreadable";
+ case 24: return "NonWritable";
+ case 25: return "NonReadable";
case 26: return "Uniform";
- case 27: return "NoStaticUse";
+ case 27: return "Bad";
case 28: return "SaturatedConversion";
case 29: return "Stream";
case 30: return "Location";
@@ -238,13 +240,16 @@
case 39: return "FP Rounding Mode";
case 40: return "FP Fast Math Mode";
case 41: return "Linkage Attributes";
+ case 42: return "NoContraction";
+ case 43: return "InputAttachmentIndex";
+ case 44: return "Alignment";
case DecorationCeiling:
default: return "Bad";
}
}
-const int BuiltInCeiling = 42;
+const int BuiltInCeiling = 44;
const char* BuiltInString(int builtIn)
{
@@ -270,7 +275,7 @@
case 18: return "SampleId";
case 19: return "SamplePosition";
case 20: return "SampleMask";
- case 21: return "FragColor";
+ case 21: return "Bad";
case 22: return "FragDepth";
case 23: return "HelperInvocation";
case 24: return "NumWorkgroups";
@@ -284,20 +289,22 @@
case 32: return "EnqueuedWorkgroupSize";
case 33: return "GlobalOffset";
case 34: return "GlobalLinearId";
- case 35: return "WorkgroupLinearId";
+ case 35: return "Bad";
case 36: return "SubgroupSize";
case 37: return "SubgroupMaxSize";
case 38: return "NumSubgroups";
case 39: return "NumEnqueuedSubgroups";
case 40: return "SubgroupId";
case 41: return "SubgroupLocalInvocationId";
+ case 42: return "VertexIndex"; // TBD: put next to VertexId?
+ case 43: return "InstanceIndex"; // TBD: put next to InstanceId?
case BuiltInCeiling:
default: return "Bad";
}
}
-const int DimensionCeiling = 6;
+const int DimensionCeiling = 7;
const char* DimensionString(int dim)
{
@@ -308,6 +315,7 @@
case 3: return "Cube";
case 4: return "Rect";
case 5: return "Buffer";
+ case 6: return "SubpassData";
case DimensionCeiling:
default: return "Bad";
@@ -438,7 +446,7 @@
}
}
-const int ImageChannelDataTypeCeiling = 16;
+const int ImageChannelDataTypeCeiling = 17;
const char* ImageChannelDataTypeString(int type)
{
@@ -460,6 +468,7 @@
case 13: return "HalfFloat";
case 14: return "Float";
case 15: return "UnormInt24";
+ case 16: return "UnormInt101010_2";
case ImageChannelDataTypeCeiling:
default:
@@ -467,7 +476,7 @@
}
}
-const int ImageOperandsCeiling = 7;
+const int ImageOperandsCeiling = 8;
const char* ImageOperandsString(int format)
{
@@ -479,6 +488,7 @@
case 4: return "Offset";
case 5: return "ConstOffsets";
case 6: return "Sample";
+ case 7: return "MinLod";
case ImageOperandsCeiling:
default:
@@ -604,35 +614,38 @@
}
}
-const int MemorySemanticsCeiling = 10;
+const int MemorySemanticsCeiling = 12;
const char* MemorySemanticsString(int mem)
{
+ // Note: No bits set (None) means "Relaxed"
switch (mem) {
- case 0: return "Relaxed";
- case 1: return "SequentiallyConsistent";
- case 2: return "Acquire";
- case 3: return "Release";
-
- case 4: return "UniformMemory";
- case 5: return "SubgroupMemory";
- case 6: return "WorkgroupLocalMemory";
- case 7: return "WorkgroupGlobalMemory";
- case 8: return "AtomicCounterMemory";
- case 9: return "ImageMemory";
+ case 0: return "Bad"; // Note: this is a placeholder for 'Consume'
+ case 1: return "Acquire";
+ case 2: return "Release";
+ case 3: return "AcquireRelease";
+ case 4: return "SequentiallyConsistent";
+ case 5: return "Bad"; // Note: reserved for future expansion
+ case 6: return "UniformMemory";
+ case 7: return "SubgroupMemory";
+ case 8: return "WorkgroupMemory";
+ case 9: return "CrossWorkgroupMemory";
+ case 10: return "AtomicCounterMemory";
+ case 11: return "ImageMemory";
case MemorySemanticsCeiling:
default: return "Bad";
}
}
-const int MemoryAccessCeiling = 2;
+const int MemoryAccessCeiling = 3;
const char* MemoryAccessString(int mem)
{
switch (mem) {
case 0: return "Volatile";
case 1: return "Aligned";
+ case 2: return "Nontemporal";
case MemoryAccessCeiling:
default: return "Bad";
@@ -699,7 +712,7 @@
}
}
-const int CapabilityCeiling = 36;
+const int CapabilityCeiling = 57;
const char* CapabilityString(int info)
{
@@ -721,7 +734,7 @@
case 13: return "ImageBasic";
case 14: return "ImageReadWrite";
case 15: return "ImageMipmap";
- case 16: return "ImageSRGBWrite";
+ case 16: return "Bad";
case 17: return "Pipes";
case 18: return "Groups";
case 19: return "DeviceEnqueue";
@@ -731,7 +744,7 @@
case 23: return "TessellationPointSize";
case 24: return "GeometryPointSize";
case 25: return "ImageGatherExtended";
- case 26: return "StorageImageExtendedFormats";
+ case 26: return "Bad";
case 27: return "StorageImageMultisample";
case 28: return "UniformBufferArrayDynamicIndexing";
case 29: return "SampledImageArrayDynamicIndexing";
@@ -741,6 +754,27 @@
case 33: return "CullDistance";
case 34: return "ImageCubeArray";
case 35: return "SampleRateShading";
+ case 36: return "ImageRect";
+ case 37: return "SampledRect";
+ case 38: return "GenericPointer";
+ case 39: return "Int8";
+ case 40: return "InputAttachment";
+ case 41: return "SparseResidency";
+ case 42: return "MinLod";
+ case 43: return "Sampled1D";
+ case 44: return "Image1D";
+ case 45: return "SampledCubeArray";
+ case 46: return "SampledBuffer";
+ case 47: return "ImageBuffer";
+ case 48: return "ImageMSArray";
+ case 49: return "StorageImageExtendedFormats";
+ case 50: return "ImageQuery";
+ case 51: return "DerivativeControl";
+ case 52: return "InterpolationFunction";
+ case 53: return "TransformFeedback";
+ case 54: return "GeometryStreams";
+ case 55: return "StorageImageReadWithoutFormat";
+ case 56: return "StorageImageWriteWithoutFormat";
case CapabilityCeiling:
default: return "Bad";
@@ -752,7 +786,7 @@
switch (op) {
case 0: return "OpNop";
case 1: return "OpUndef";
- case 2: return "Bad";
+ case 2: return "OpSourceContinued";
case 3: return "OpSource";
case 4: return "OpSourceExtension";
case 5: return "OpName";
@@ -789,7 +823,7 @@
case 36: return "OpTypeReserveId";
case 37: return "OpTypeQueue";
case 38: return "OpTypePipe";
- case 39: return "Bad";
+ case 39: return "OpTypeForwardPointer";
case 40: return "Bad";
case 41: return "OpConstantTrue";
case 42: return "OpConstantFalse";
@@ -820,7 +854,7 @@
case 67: return "OpPtrAccessChain";
case 68: return "OpArrayLength";
case 69: return "OpGenericPtrMemSemantics";
- case 70: return "Bad";
+ case 70: return "OpInBoundsPtrAccessChain";
case 71: return "OpDecorate";
case 72: return "OpMemberDecorate";
case 73: return "OpDecorationGroup";
@@ -850,7 +884,7 @@
case 97: return "OpImageDrefGather";
case 98: return "OpImageRead";
case 99: return "OpImageWrite";
- case 100: return "OpImageQueryDim";
+ case 100: return "OpImage";
case 101: return "OpImageQueryFormat";
case 102: return "OpImageQueryOrder";
case 103: return "OpImageQuerySizeLod";
@@ -901,8 +935,8 @@
case 148: return "OpDot";
case 149: return "OpIAddCarry";
case 150: return "OpISubBorrow";
- case 151: return "OpIMulExtended";
- case 152: return "Bad";
+ case 151: return "OpUMulExtended";
+ case 152: return "OpSMulExtended";
case 153: return "Bad";
case 154: return "OpAny";
case 155: return "OpAll";
@@ -1009,8 +1043,8 @@
case 256: return "OpLifetimeStart";
case 257: return "OpLifetimeStop";
case 258: return "Bad";
- case 259: return "OpAsyncGroupCopy";
- case 260: return "OpWaitGroupEvents";
+ case 259: return "OpGroupAsyncCopy";
+ case 260: return "OpGroupWaitEvents";
case 261: return "OpGroupAll";
case 262: return "OpGroupAny";
case 263: return "OpGroupBroadcast";
@@ -1055,6 +1089,21 @@
case 302: return "OpCaptureEventProfilingInfo";
case 303: return "OpGetDefaultQueue";
case 304: return "OpBuildNDRange";
+ case 305: return "OpImageSparseSampleImplicitLod";
+ case 306: return "OpImageSparseSampleExplicitLod";
+ case 307: return "OpImageSparseSampleDrefImplicitLod";
+ case 308: return "OpImageSparseSampleDrefExplicitLod";
+ case 309: return "OpImageSparseSampleProjImplicitLod";
+ case 310: return "OpImageSparseSampleProjExplicitLod";
+ case 311: return "OpImageSparseSampleProjDrefImplicitLod";
+ case 312: return "OpImageSparseSampleProjDrefExplicitLod";
+ case 313: return "OpImageSparseFetch";
+ case 314: return "OpImageSparseGather";
+ case 315: return "OpImageSparseDrefGather";
+ case 316: return "OpImageSparseTexelsResident";
+ case 317: return "OpNoLine";
+ case 318: return "OpAtomicFlagTestAndSet";
+ case 319: return "OpAtomicFlagClear";
case OpcodeCeiling:
default:
@@ -1113,6 +1162,7 @@
InstructionDesc[OpNop].setResultAndType(false, false);
InstructionDesc[OpSource].setResultAndType(false, false);
+ InstructionDesc[OpSourceContinued].setResultAndType(false, false);
InstructionDesc[OpSourceExtension].setResultAndType(false, false);
InstructionDesc[OpExtension].setResultAndType(false, false);
InstructionDesc[OpExtInstImport].setResultAndType(true, false);
@@ -1134,6 +1184,7 @@
InstructionDesc[OpTypeStruct].setResultAndType(true, false);
InstructionDesc[OpTypeOpaque].setResultAndType(true, false);
InstructionDesc[OpTypePointer].setResultAndType(true, false);
+ InstructionDesc[OpTypeForwardPointer].setResultAndType(false, false);
InstructionDesc[OpTypeFunction].setResultAndType(true, false);
InstructionDesc[OpTypeEvent].setResultAndType(true, false);
InstructionDesc[OpTypeDeviceEvent].setResultAndType(true, false);
@@ -1152,6 +1203,7 @@
InstructionDesc[OpMemberName].setResultAndType(false, false);
InstructionDesc[OpString].setResultAndType(true, false);
InstructionDesc[OpLine].setResultAndType(false, false);
+ InstructionDesc[OpNoLine].setResultAndType(false, false);
InstructionDesc[OpCopyMemory].setResultAndType(false, false);
InstructionDesc[OpCopyMemorySized].setResultAndType(false, false);
InstructionDesc[OpEmitVertex].setResultAndType(false, false);
@@ -1181,11 +1233,12 @@
InstructionDesc[OpSetUserEventStatus].setResultAndType(false, false);
InstructionDesc[OpRetainEvent].setResultAndType(false, false);
InstructionDesc[OpReleaseEvent].setResultAndType(false, false);
- InstructionDesc[OpWaitGroupEvents].setResultAndType(false, false);
+ InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false);
+ InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false);
// Specific additional context-dependent operands
- ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "Number of <<Invocation,invocations>>");
+ ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "'Number of <<Invocation,invocations>>'");
ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'x size'");
ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'y size'");
@@ -1198,24 +1251,26 @@
ExecutionModeOperands[ExecutionModeOutputVertices].push(OperandLiteralNumber, "'Vertex count'");
ExecutionModeOperands[ExecutionModeVecTypeHint].push(OperandLiteralNumber, "'Vector type'");
- DecorationOperands[DecorationStream].push(OperandLiteralNumber, "Stream number");
- DecorationOperands[DecorationLocation].push(OperandLiteralNumber, "Location");
- DecorationOperands[DecorationComponent].push(OperandLiteralNumber, "Component within a vector");
- DecorationOperands[DecorationIndex].push(OperandLiteralNumber, "Index");
- DecorationOperands[DecorationBinding].push(OperandLiteralNumber, "Binding point");
- DecorationOperands[DecorationDescriptorSet].push(OperandLiteralNumber, "Descriptor set");
- DecorationOperands[DecorationOffset].push(OperandLiteralNumber, "Byte offset");
- DecorationOperands[DecorationXfbBuffer].push(OperandLiteralNumber, "XFB buffer number");
- DecorationOperands[DecorationXfbStride].push(OperandLiteralNumber, "XFB stride");
- DecorationOperands[DecorationArrayStride].push(OperandLiteralNumber, "Array stride");
- DecorationOperands[DecorationMatrixStride].push(OperandLiteralNumber, "Matrix stride");
+ DecorationOperands[DecorationStream].push(OperandLiteralNumber, "'Stream Number'");
+ DecorationOperands[DecorationLocation].push(OperandLiteralNumber, "'Location'");
+ DecorationOperands[DecorationComponent].push(OperandLiteralNumber, "'Component'");
+ DecorationOperands[DecorationIndex].push(OperandLiteralNumber, "'Index'");
+ DecorationOperands[DecorationBinding].push(OperandLiteralNumber, "'Binding Point'");
+ DecorationOperands[DecorationDescriptorSet].push(OperandLiteralNumber, "'Descriptor Set'");
+ DecorationOperands[DecorationOffset].push(OperandLiteralNumber, "'Byte Offset'");
+ DecorationOperands[DecorationXfbBuffer].push(OperandLiteralNumber, "'XFB Buffer Number'");
+ DecorationOperands[DecorationXfbStride].push(OperandLiteralNumber, "'XFB Stride'");
+ DecorationOperands[DecorationArrayStride].push(OperandLiteralNumber, "'Array Stride'");
+ DecorationOperands[DecorationMatrixStride].push(OperandLiteralNumber, "'Matrix Stride'");
DecorationOperands[DecorationBuiltIn].push(OperandLiteralNumber, "See <<BuiltIn,*BuiltIn*>>");
- DecorationOperands[DecorationFPRoundingMode].push(OperandFPRoundingMode, "floating-point rounding mode");
- DecorationOperands[DecorationFPFastMathMode].push(OperandFPFastMath, "fast-math mode");
- DecorationOperands[DecorationLinkageAttributes].push(OperandLiteralString, "name");
- DecorationOperands[DecorationLinkageAttributes].push(OperandLinkageType, "linkage type");
- DecorationOperands[DecorationFuncParamAttr].push(OperandFuncParamAttr, "function parameter attribute");
- DecorationOperands[DecorationSpecId].push(OperandLiteralNumber, "Specialization Constant ID");
+ DecorationOperands[DecorationFPRoundingMode].push(OperandFPRoundingMode, "'Floating-Point Rounding Mode'");
+ DecorationOperands[DecorationFPFastMathMode].push(OperandFPFastMath, "'Fast-Math Mode'");
+ DecorationOperands[DecorationLinkageAttributes].push(OperandLiteralString, "'Name'");
+ DecorationOperands[DecorationLinkageAttributes].push(OperandLinkageType, "'Linkage Type'");
+ DecorationOperands[DecorationFuncParamAttr].push(OperandFuncParamAttr, "'Function Parameter Attribute'");
+ DecorationOperands[DecorationSpecId].push(OperandLiteralNumber, "'Specialization Constant ID'");
+ DecorationOperands[DecorationInputAttachmentIndex].push(OperandLiteralNumber, "'Attachment Index'");
+ DecorationOperands[DecorationAlignment].push(OperandLiteralNumber, "'Alignment'");
OperandClassParams[OperandSource].set(SourceLanguageCeiling, SourceString, 0);
OperandClassParams[OperandExecutionModel].set(ExecutionModelCeiling, ExecutionModelString, ExecutionModelParams);
@@ -1251,6 +1306,54 @@
OperandClassParams[OperandCapability].set(CapabilityCeiling, CapabilityString, CapabilityParams);
OperandClassParams[OperandOpcode].set(OpcodeCeiling, OpcodeString, 0);
+ CapabilityParams[CapabilityShader].caps.push_back(CapabilityMatrix);
+ CapabilityParams[CapabilityGeometry].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityTessellation].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityVector16].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityFloat16Buffer].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityFloat16].caps.push_back(CapabilityFloat16Buffer);
+ CapabilityParams[CapabilityInt64Atomics].caps.push_back(CapabilityInt64);
+ CapabilityParams[CapabilityImageBasic].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityImageReadWrite].caps.push_back(CapabilityImageBasic);
+ CapabilityParams[CapabilityImageMipmap].caps.push_back(CapabilityImageBasic);
+ CapabilityParams[CapabilityPipes].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityDeviceEnqueue].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityLiteralSampler].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityAtomicStorage].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampleRateShading].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityTessellationPointSize].caps.push_back(CapabilityTessellation);
+ CapabilityParams[CapabilityGeometryPointSize].caps.push_back(CapabilityGeometry);
+ CapabilityParams[CapabilityImageGatherExtended].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityStorageImageExtendedFormats].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityStorageImageMultisample].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityUniformBufferArrayDynamicIndexing].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampledImageArrayDynamicIndexing].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityStorageBufferArrayDynamicIndexing].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityStorageImageArrayDynamicIndexing].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityClipDistance].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityCullDistance].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityGenericPointer].caps.push_back(CapabilityAddresses);
+ CapabilityParams[CapabilityInt8].caps.push_back(CapabilityKernel);
+ CapabilityParams[CapabilityInputAttachment].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityMinLod].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySparseResidency].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampled1D].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampledRect].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampledBuffer].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilitySampledCubeArray].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityImageMSArray].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityImage1D].caps.push_back(CapabilitySampled1D);
+ CapabilityParams[CapabilityImageRect].caps.push_back(CapabilitySampledRect);
+ CapabilityParams[CapabilityImageBuffer].caps.push_back(CapabilitySampledBuffer);
+ CapabilityParams[CapabilityImageCubeArray].caps.push_back(CapabilitySampledCubeArray);
+ CapabilityParams[CapabilityImageQuery].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityDerivativeControl].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityInterpolationFunction].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityTransformFeedback].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityGeometryStreams].caps.push_back(CapabilityGeometry);
+ CapabilityParams[CapabilityStorageImageReadWithoutFormat].caps.push_back(CapabilityShader);
+ CapabilityParams[CapabilityStorageImageWriteWithoutFormat].caps.push_back(CapabilityShader);
+
AddressingParams[AddressingModelPhysical32].caps.push_back(CapabilityAddresses);
AddressingParams[AddressingModelPhysical64].caps.push_back(CapabilityAddresses);
@@ -1258,6 +1361,9 @@
MemoryParams[MemoryModelGLSL450].caps.push_back(CapabilityShader);
MemoryParams[MemoryModelOpenCL].caps.push_back(CapabilityKernel);
+ MemorySemanticsParams[MemorySemanticsUniformMemoryShift].caps.push_back(CapabilityShader);
+ MemorySemanticsParams[MemorySemanticsAtomicCounterMemoryShift].caps.push_back(CapabilityShader);
+
ExecutionModelParams[ExecutionModelVertex].caps.push_back(CapabilityShader);
ExecutionModelParams[ExecutionModelTessellationControl].caps.push_back(CapabilityTessellation);
ExecutionModelParams[ExecutionModelTessellationEvaluation].caps.push_back(CapabilityTessellation);
@@ -1270,10 +1376,10 @@
StorageParams[StorageClassInput].caps.push_back(CapabilityShader);
StorageParams[StorageClassUniform].caps.push_back(CapabilityShader);
StorageParams[StorageClassOutput].caps.push_back(CapabilityShader);
- StorageParams[StorageClassPrivateGlobal].caps.push_back(CapabilityShader);
+ StorageParams[StorageClassPrivate].caps.push_back(CapabilityShader);
StorageParams[StorageClassGeneric].caps.push_back(CapabilityKernel);
StorageParams[StorageClassAtomicCounter].caps.push_back(CapabilityAtomicStorage);
-
+ StorageParams[StorageClassPushConstant].caps.push_back(CapabilityShader);
// Sampler Filter & Addressing mode capabilities
SamplerAddressingModeParams[SamplerAddressingModeNone].caps.push_back(CapabilityKernel);
@@ -1286,9 +1392,57 @@
SamplerFilterModeParams[SamplerFilterModeLinear].caps.push_back(CapabilityKernel);
// image format capabilities
- for (int i = 0; i < ImageFormatCeiling; ++i) {
- ImageFormatParams[i].caps.push_back(CapabilityShader);
- }
+
+ // ES/Desktop float
+ ImageFormatParams[ImageFormatRgba32f].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba16f].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatR32f].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba8].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba8Snorm].caps.push_back(CapabilityShader);
+
+ // Desktop float
+ ImageFormatParams[ImageFormatRg32f].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg16f].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR11fG11fB10f].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR16f].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRgba16].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRgb10A2].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg16].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg8].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR16].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR8].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRgba16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg8Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR16Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR8Snorm].caps.push_back(CapabilityStorageImageExtendedFormats);
+
+ // ES/Desktop int
+ ImageFormatParams[ImageFormatRgba32i].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba16i].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba8i].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatR32i].caps.push_back(CapabilityShader);
+
+ // Desktop int
+ ImageFormatParams[ImageFormatRg32i].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg16i].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg8i].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR16i].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR8i].caps.push_back(CapabilityStorageImageExtendedFormats);
+
+ // ES/Desktop uint
+ ImageFormatParams[ImageFormatRgba32ui].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba16ui].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatRgba8ui].caps.push_back(CapabilityShader);
+ ImageFormatParams[ImageFormatR32ui].caps.push_back(CapabilityShader);
+
+ // Desktop uint
+ ImageFormatParams[ImageFormatRgb10a2ui].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg32ui].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg16ui].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatRg8ui].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR16ui].caps.push_back(CapabilityStorageImageExtendedFormats);
+ ImageFormatParams[ImageFormatR8ui].caps.push_back(CapabilityStorageImageExtendedFormats);
// image channel order capabilities
for (int i = 0; i < ImageChannelOrderCeiling; ++i) {
@@ -1303,6 +1457,7 @@
// image lookup operands
ImageOperandsParams[ImageOperandsBiasShift].caps.push_back(CapabilityShader);
ImageOperandsParams[ImageOperandsOffsetShift].caps.push_back(CapabilityImageGatherExtended);
+ ImageOperandsParams[ImageOperandsMinLodShift].caps.push_back(CapabilityMinLod);
// fast math flags capabilities
for (int i = 0; i < FPFastMathCeiling; ++i) {
@@ -1340,9 +1495,8 @@
ExecutionModeParams[ExecutionModeOriginLowerLeft].caps.push_back(CapabilityShader);
ExecutionModeParams[ExecutionModeEarlyFragmentTests].caps.push_back(CapabilityShader);
ExecutionModeParams[ExecutionModePointMode].caps.push_back(CapabilityTessellation);
- ExecutionModeParams[ExecutionModeXfb].caps.push_back(CapabilityShader);
+ ExecutionModeParams[ExecutionModeXfb].caps.push_back(CapabilityTransformFeedback);
ExecutionModeParams[ExecutionModeDepthReplacing].caps.push_back(CapabilityShader);
- ExecutionModeParams[ExecutionModeDepthAny].caps.push_back(CapabilityShader);
ExecutionModeParams[ExecutionModeDepthGreater].caps.push_back(CapabilityShader);
ExecutionModeParams[ExecutionModeDepthLess].caps.push_back(CapabilityShader);
ExecutionModeParams[ExecutionModeDepthUnchanged].caps.push_back(CapabilityShader);
@@ -1350,11 +1504,11 @@
ExecutionModeParams[ExecutionModeInputPoints].caps.push_back(CapabilityGeometry);
ExecutionModeParams[ExecutionModeInputLines].caps.push_back(CapabilityGeometry);
ExecutionModeParams[ExecutionModeInputLinesAdjacency].caps.push_back(CapabilityGeometry);
- ExecutionModeParams[ExecutionModeInputTriangles].caps.push_back(CapabilityGeometry);
- ExecutionModeParams[ExecutionModeInputTriangles].caps.push_back(CapabilityTessellation);
+ ExecutionModeParams[ExecutionModeTriangles].caps.push_back(CapabilityGeometry);
+ ExecutionModeParams[ExecutionModeTriangles].caps.push_back(CapabilityTessellation);
ExecutionModeParams[ExecutionModeInputTrianglesAdjacency].caps.push_back(CapabilityGeometry);
- ExecutionModeParams[ExecutionModeInputQuads].caps.push_back(CapabilityTessellation);
- ExecutionModeParams[ExecutionModeInputIsolines].caps.push_back(CapabilityTessellation);
+ ExecutionModeParams[ExecutionModeQuads].caps.push_back(CapabilityTessellation);
+ ExecutionModeParams[ExecutionModeIsolines].caps.push_back(CapabilityTessellation);
ExecutionModeParams[ExecutionModeOutputVertices].caps.push_back(CapabilityGeometry);
ExecutionModeParams[ExecutionModeOutputVertices].caps.push_back(CapabilityTessellation);
ExecutionModeParams[ExecutionModeOutputPoints].caps.push_back(CapabilityGeometry);
@@ -1370,8 +1524,7 @@
DecorationParams[DecorationColMajor].caps.push_back(CapabilityMatrix);
DecorationParams[DecorationGLSLShared].caps.push_back(CapabilityShader);
DecorationParams[DecorationGLSLPacked].caps.push_back(CapabilityShader);
- DecorationParams[DecorationSmooth].caps.push_back(CapabilityShader);
- DecorationParams[DecorationNoperspective].caps.push_back(CapabilityShader);
+ DecorationParams[DecorationNoPerspective].caps.push_back(CapabilityShader);
DecorationParams[DecorationFlat].caps.push_back(CapabilityShader);
DecorationParams[DecorationPatch].caps.push_back(CapabilityTessellation);
DecorationParams[DecorationCentroid].caps.push_back(CapabilityShader);
@@ -1381,14 +1534,14 @@
DecorationParams[DecorationUniform].caps.push_back(CapabilityShader);
DecorationParams[DecorationCPacked].caps.push_back(CapabilityKernel);
DecorationParams[DecorationSaturatedConversion].caps.push_back(CapabilityKernel);
- DecorationParams[DecorationStream].caps.push_back(CapabilityGeometry);
+ DecorationParams[DecorationStream].caps.push_back(CapabilityGeometryStreams);
DecorationParams[DecorationLocation].caps.push_back(CapabilityShader);
DecorationParams[DecorationComponent].caps.push_back(CapabilityShader);
DecorationParams[DecorationIndex].caps.push_back(CapabilityShader);
DecorationParams[DecorationBinding].caps.push_back(CapabilityShader);
DecorationParams[DecorationDescriptorSet].caps.push_back(CapabilityShader);
- DecorationParams[DecorationXfbBuffer].caps.push_back(CapabilityShader);
- DecorationParams[DecorationXfbStride].caps.push_back(CapabilityShader);
+ DecorationParams[DecorationXfbBuffer].caps.push_back(CapabilityTransformFeedback);
+ DecorationParams[DecorationXfbStride].caps.push_back(CapabilityTransformFeedback);
DecorationParams[DecorationArrayStride].caps.push_back(CapabilityShader);
DecorationParams[DecorationMatrixStride].caps.push_back(CapabilityShader);
DecorationParams[DecorationBuiltIn].caps.push_back(CapabilityShader);
@@ -1397,13 +1550,27 @@
DecorationParams[DecorationFPFastMathMode].caps.push_back(CapabilityKernel);
DecorationParams[DecorationLinkageAttributes].caps.push_back(CapabilityLinkage);
DecorationParams[DecorationSpecId].caps.push_back(CapabilityShader);
+ DecorationParams[DecorationNoContraction].caps.push_back(CapabilityShader);
+ DecorationParams[DecorationInputAttachmentIndex].caps.push_back(CapabilityInputAttachment);
+ DecorationParams[DecorationAlignment].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInPosition].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInPointSize].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInClipDistance].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInCullDistance].caps.push_back(CapabilityShader);
+
BuiltInParams[BuiltInVertexId].caps.push_back(CapabilityShader);
+ BuiltInParams[BuiltInVertexId].desc = "Vertex ID, which takes on values 0, 1, 2, . . . .";
+
BuiltInParams[BuiltInInstanceId].caps.push_back(CapabilityShader);
+ BuiltInParams[BuiltInInstanceId].desc = "Instance ID, which takes on values 0, 1, 2, . . . .";
+
+ BuiltInParams[BuiltInVertexIndex].caps.push_back(CapabilityShader);
+ BuiltInParams[BuiltInVertexIndex].desc = "Vertex index, which takes on values base, base+1, base+2, . . . .";
+
+ BuiltInParams[BuiltInInstanceIndex].caps.push_back(CapabilityShader);
+ BuiltInParams[BuiltInInstanceIndex].desc = "Instance index, which takes on values base, base+1, base+2, . . . .";
+
BuiltInParams[BuiltInPrimitiveId].caps.push_back(CapabilityGeometry);
BuiltInParams[BuiltInPrimitiveId].caps.push_back(CapabilityTessellation);
BuiltInParams[BuiltInInvocationId].caps.push_back(CapabilityGeometry);
@@ -1420,16 +1587,13 @@
BuiltInParams[BuiltInSampleId].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInSamplePosition].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInSampleMask].caps.push_back(CapabilityShader);
- BuiltInParams[BuiltInFragColor].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInFragDepth].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInHelperInvocation].caps.push_back(CapabilityShader);
- BuiltInParams[BuiltInLocalInvocationIndex].caps.push_back(CapabilityShader);
BuiltInParams[BuiltInWorkDim].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInGlobalSize].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInEnqueuedWorkgroupSize].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInGlobalOffset].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInGlobalLinearId].caps.push_back(CapabilityKernel);
- BuiltInParams[BuiltInWorkgroupLinearId].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInSubgroupSize].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInSubgroupMaxSize].caps.push_back(CapabilityKernel);
@@ -1438,8 +1602,11 @@
BuiltInParams[BuiltInSubgroupId].caps.push_back(CapabilityKernel);
BuiltInParams[BuiltInSubgroupLocalInvocationId].caps.push_back(CapabilityKernel);
+ DimensionalityParams[Dim1D].caps.push_back(CapabilitySampled1D);
DimensionalityParams[DimCube].caps.push_back(CapabilityShader);
- DimensionalityParams[DimRect].caps.push_back(CapabilityShader);
+ DimensionalityParams[DimRect].caps.push_back(CapabilitySampledRect);
+ DimensionalityParams[DimBuffer].caps.push_back(CapabilitySampledBuffer);
+ DimensionalityParams[DimSubpassData].caps.push_back(CapabilityInputAttachment);
// Group Operations
for (int i = 0; i < GroupOperationCeiling; ++i) {
@@ -1458,6 +1625,10 @@
InstructionDesc[OpSource].operands.push(OperandSource, "");
InstructionDesc[OpSource].operands.push(OperandLiteralNumber, "'Version'");
+ InstructionDesc[OpSource].operands.push(OperandId, "'File'", true);
+ InstructionDesc[OpSource].operands.push(OperandLiteralString, "'Source'", true);
+
+ InstructionDesc[OpSourceContinued].operands.push(OperandLiteralString, "'Continued Source'");
InstructionDesc[OpSourceExtension].operands.push(OperandLiteralString, "'Extension'");
@@ -1470,7 +1641,6 @@
InstructionDesc[OpString].operands.push(OperandLiteralString, "'String'");
- InstructionDesc[OpLine].operands.push(OperandId, "'Target'");
InstructionDesc[OpLine].operands.push(OperandId, "'File'");
InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Line'");
InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Column'");
@@ -1487,10 +1657,11 @@
InstructionDesc[OpEntryPoint].operands.push(OperandExecutionModel, "");
InstructionDesc[OpEntryPoint].operands.push(OperandId, "'Entry Point'");
InstructionDesc[OpEntryPoint].operands.push(OperandLiteralString, "'Name'");
+ InstructionDesc[OpEntryPoint].operands.push(OperandVariableIds, "'Interface'");
InstructionDesc[OpExecutionMode].operands.push(OperandId, "'Entry Point'");
InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'");
- InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution Mode,Execution Mode>>");
+ InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <<Execution_Mode,Execution Mode>>");
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'");
InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'");
@@ -1511,7 +1682,7 @@
InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'MS'");
InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Sampled'");
InstructionDesc[OpTypeImage].operands.push(OperandSamplerImageFormat, "");
- InstructionDesc[OpTypeImage].operands.push(OperandOptionalLiteral, "'Access Qualifier'");
+ InstructionDesc[OpTypeImage].operands.push(OperandAccessQualifier, "", true);
InstructionDesc[OpTypeSampledImage].operands.push(OperandId, "'Image Type'");
@@ -1529,15 +1700,18 @@
InstructionDesc[OpTypePointer].operands.push(OperandStorage, "");
InstructionDesc[OpTypePointer].operands.push(OperandId, "'Type'");
+ InstructionDesc[OpTypeForwardPointer].capabilities.push_back(CapabilityAddresses);
+ InstructionDesc[OpTypeForwardPointer].operands.push(OperandId, "'Pointer Type'");
+ InstructionDesc[OpTypeForwardPointer].operands.push(OperandStorage, "");
+
InstructionDesc[OpTypeEvent].capabilities.push_back(CapabilityKernel);
- InstructionDesc[OpTypeDeviceEvent].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpTypeDeviceEvent].capabilities.push_back(CapabilityDeviceEnqueue);
InstructionDesc[OpTypeReserveId].capabilities.push_back(CapabilityPipes);
- InstructionDesc[OpTypeQueue].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpTypeQueue].capabilities.push_back(CapabilityDeviceEnqueue);
- InstructionDesc[OpTypePipe].operands.push(OperandId, "'Type'");
InstructionDesc[OpTypePipe].operands.push(OperandAccessQualifier, "'Qualifier'");
InstructionDesc[OpTypePipe].capabilities.push_back(CapabilityPipes);
@@ -1561,7 +1735,7 @@
InstructionDesc[OpSpecConstantOp].operands.push(OperandVariableIds, "'Operands'");
InstructionDesc[OpVariable].operands.push(OperandStorage, "");
- InstructionDesc[OpVariable].operands.push(OperandOptionalId, "'Initializer'");
+ InstructionDesc[OpVariable].operands.push(OperandId, "'Initializer'", true);
InstructionDesc[OpFunction].operands.push(OperandFunction, "");
InstructionDesc[OpFunction].operands.push(OperandId, "'Function Type'");
@@ -1574,11 +1748,11 @@
InstructionDesc[OpExtInst].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n...");
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
- InstructionDesc[OpLoad].operands.push(OperandOptionalLiteral, "'Memory Access'");
+ InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
- InstructionDesc[OpStore].operands.push(OperandOptionalLiteral, "'Memory Access'");
+ InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
@@ -1621,101 +1795,196 @@
InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Target'");
InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Source'");
- InstructionDesc[OpCopyMemory].operands.push(OperandOptionalLiteral, "'Memory Access'");
+ InstructionDesc[OpCopyMemory].operands.push(OperandMemoryAccess, "", true);
InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Target'");
InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Source'");
InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Size'");
- InstructionDesc[OpCopyMemorySized].operands.push(OperandOptionalLiteral, "'Memory Access'");
+ InstructionDesc[OpCopyMemorySized].operands.push(OperandMemoryAccess, "", true);
InstructionDesc[OpCopyMemorySized].capabilities.push_back(CapabilityAddresses);
InstructionDesc[OpSampledImage].operands.push(OperandId, "'Image'");
InstructionDesc[OpSampledImage].operands.push(OperandId, "'Sampler'");
+ InstructionDesc[OpImage].operands.push(OperandId, "'Sampled Image'");
+
InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageRead].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageRead].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'");
+ InstructionDesc[OpImageWrite].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageWrite].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleImplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
- InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleDrefImplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
- InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleDrefExplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleProjImplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleProjExplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
- InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleProjDrefImplicitLod].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
- InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageSampleProjDrefExplicitLod].capabilities.push_back(CapabilityShader);
- InstructionDesc[OpImageFetch].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageFetch].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageFetch].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageFetch].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageFetch].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageFetch].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageGather].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageGather].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageGather].operands.push(OperandId, "'Component'");
- InstructionDesc[OpImageGather].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageGather].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageGather].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageGather].capabilities.push_back(CapabilityShader);
InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Sampled Image'");
InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Coordinate'");
InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'D~ref~'");
- InstructionDesc[OpImageDrefGather].operands.push(OperandOptionalImage, "");
+ InstructionDesc[OpImageDrefGather].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageDrefGather].operands.push(OperandVariableIds, "", true);
InstructionDesc[OpImageDrefGather].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleImplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleExplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleDrefImplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleDrefExplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleProjImplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleProjExplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'");
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'");
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Image'");
+ InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseFetch].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseFetch].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseFetch].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Component'");
+ InstructionDesc[OpImageSparseGather].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseGather].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseGather].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Sampled Image'");
+ InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Coordinate'");
+ InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'D~ref~'");
+ InstructionDesc[OpImageSparseDrefGather].operands.push(OperandImageOperands, "", true);
+ InstructionDesc[OpImageSparseDrefGather].operands.push(OperandVariableIds, "", true);
+ InstructionDesc[OpImageSparseDrefGather].capabilities.push_back(CapabilitySparseResidency);
+
+ InstructionDesc[OpImageSparseTexelsResident].operands.push(OperandId, "'Resident Code'");
+ InstructionDesc[OpImageSparseTexelsResident].capabilities.push_back(CapabilitySparseResidency);
+
InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Level of Detail'");
+ InstructionDesc[OpImageQuerySizeLod].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpImageQuerySizeLod].capabilities.push_back(CapabilityImageQuery);
InstructionDesc[OpImageQuerySize].operands.push(OperandId, "'Image'");
+ InstructionDesc[OpImageQuerySize].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpImageQuerySize].capabilities.push_back(CapabilityImageQuery);
InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Coordinate'");
- InstructionDesc[OpImageQueryLod].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpImageQueryLod].capabilities.push_back(CapabilityImageQuery);
InstructionDesc[OpImageQueryLevels].operands.push(OperandId, "'Image'");
- InstructionDesc[OpImageQueryLevels].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpImageQueryLevels].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpImageQueryLevels].capabilities.push_back(CapabilityImageQuery);
InstructionDesc[OpImageQuerySamples].operands.push(OperandId, "'Image'");
- InstructionDesc[OpImageQuerySamples].capabilities.push_back(CapabilityShader);
-
- InstructionDesc[OpImageQueryDim].operands.push(OperandId, "'Image'");
- InstructionDesc[OpImageQueryDim].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpImageQuerySamples].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpImageQuerySamples].capabilities.push_back(CapabilityImageQuery);
InstructionDesc[OpImageQueryFormat].operands.push(OperandId, "'Image'");
InstructionDesc[OpImageQueryFormat].capabilities.push_back(CapabilityKernel);
@@ -1734,6 +2003,11 @@
InstructionDesc[OpPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'");
InstructionDesc[OpPtrAccessChain].capabilities.push_back(CapabilityAddresses);
+ InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Base'");
+ InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Element'");
+ InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'");
+ InstructionDesc[OpInBoundsPtrAccessChain].capabilities.push_back(CapabilityAddresses);
+
InstructionDesc[OpSNegate].operands.push(OperandId, "'Operand'");
InstructionDesc[OpFNegate].operands.push(OperandId, "'Operand'");
@@ -1887,6 +2161,18 @@
InstructionDesc[OpDot].operands.push(OperandId, "'Vector 1'");
InstructionDesc[OpDot].operands.push(OperandId, "'Vector 2'");
+ InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 1'");
+ InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 2'");
+
+ InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 1'");
+ InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 2'");
+
+ InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 1'");
+ InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 2'");
+
+ InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 1'");
+ InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 2'");
+
InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Base'");
InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Shift'");
@@ -2019,22 +2305,22 @@
InstructionDesc[OpFwidth].capabilities.push_back(CapabilityShader);
InstructionDesc[OpFwidth].operands.push(OperandId, "'P'");
- InstructionDesc[OpDPdxFine].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpDPdxFine].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpDPdxFine].operands.push(OperandId, "'P'");
- InstructionDesc[OpDPdyFine].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpDPdyFine].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpDPdyFine].operands.push(OperandId, "'P'");
- InstructionDesc[OpFwidthFine].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpFwidthFine].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpFwidthFine].operands.push(OperandId, "'P'");
- InstructionDesc[OpDPdxCoarse].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpDPdxCoarse].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpDPdxCoarse].operands.push(OperandId, "'P'");
- InstructionDesc[OpDPdyCoarse].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpDPdyCoarse].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpDPdyCoarse].operands.push(OperandId, "'P'");
- InstructionDesc[OpFwidthCoarse].capabilities.push_back(CapabilityShader);
+ InstructionDesc[OpFwidthCoarse].capabilities.push_back(CapabilityDerivativeControl);
InstructionDesc[OpFwidthCoarse].operands.push(OperandId, "'P'");
InstructionDesc[OpEmitVertex].capabilities.push_back(CapabilityGeometry);
@@ -2042,10 +2328,10 @@
InstructionDesc[OpEndPrimitive].capabilities.push_back(CapabilityGeometry);
InstructionDesc[OpEmitStreamVertex].operands.push(OperandId, "'Stream'");
- InstructionDesc[OpEmitStreamVertex].capabilities.push_back(CapabilityGeometry);
+ InstructionDesc[OpEmitStreamVertex].capabilities.push_back(CapabilityGeometryStreams);
InstructionDesc[OpEndStreamPrimitive].operands.push(OperandId, "'Stream'");
- InstructionDesc[OpEndStreamPrimitive].capabilities.push_back(CapabilityGeometry);
+ InstructionDesc[OpEndStreamPrimitive].capabilities.push_back(CapabilityGeometryStreams);
InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Memory'");
@@ -2140,7 +2426,18 @@
InstructionDesc[OpAtomicXor].operands.push(OperandMemorySemantics, "'Semantics'");
InstructionDesc[OpAtomicXor].operands.push(OperandId, "'Value'");
+ InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandScope, "'Scope'");
+ InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandMemorySemantics, "'Semantics'");
+ InstructionDesc[OpAtomicFlagTestAndSet].capabilities.push_back(CapabilityKernel);
+
+ InstructionDesc[OpAtomicFlagClear].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpAtomicFlagClear].operands.push(OperandScope, "'Scope'");
+ InstructionDesc[OpAtomicFlagClear].operands.push(OperandMemorySemantics, "'Semantics'");
+ InstructionDesc[OpAtomicFlagClear].capabilities.push_back(CapabilityKernel);
+
InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'");
+ InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'");
InstructionDesc[OpLoopMerge].operands.push(OperandLoop, "");
InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'");
@@ -2163,22 +2460,24 @@
InstructionDesc[OpLifetimeStart].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpLifetimeStart].operands.push(OperandLiteralNumber, "'Size'");
+ InstructionDesc[OpLifetimeStart].capabilities.push_back(CapabilityKernel);
InstructionDesc[OpLifetimeStop].operands.push(OperandId, "'Pointer'");
InstructionDesc[OpLifetimeStop].operands.push(OperandLiteralNumber, "'Size'");
+ InstructionDesc[OpLifetimeStop].capabilities.push_back(CapabilityKernel);
- InstructionDesc[OpAsyncGroupCopy].capabilities.push_back(CapabilityKernel);
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandScope, "'Execution'");
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId, "'Destination'");
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId, "'Source'");
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId, "'Num Elements'");
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId, "'Stride'");
- InstructionDesc[OpAsyncGroupCopy].operands.push(OperandId, "'Event'");
+ InstructionDesc[OpGroupAsyncCopy].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandScope, "'Execution'");
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Destination'");
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Source'");
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Num Elements'");
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Stride'");
+ InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Event'");
- InstructionDesc[OpWaitGroupEvents].capabilities.push_back(CapabilityKernel);
- InstructionDesc[OpWaitGroupEvents].operands.push(OperandScope, "'Execution'");
- InstructionDesc[OpWaitGroupEvents].operands.push(OperandId, "'Num Events'");
- InstructionDesc[OpWaitGroupEvents].operands.push(OperandId, "'Events List'");
+ InstructionDesc[OpGroupWaitEvents].capabilities.push_back(CapabilityKernel);
+ InstructionDesc[OpGroupWaitEvents].operands.push(OperandScope, "'Execution'");
+ InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Num Events'");
+ InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Events List'");
InstructionDesc[OpGroupAll].capabilities.push_back(CapabilityGroups);
InstructionDesc[OpGroupAll].operands.push(OperandScope, "'Execution'");
@@ -2236,67 +2535,95 @@
InstructionDesc[OpReadPipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpWritePipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpReservedReadPipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Reserve Id'");
InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Index'");
InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpReservedWritePipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Reserve Id'");
InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Index'");
InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pointer'");
+ InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpReserveReadPipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Num Packets'");
+ InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpReserveWritePipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Num Packets'");
+ InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpCommitReadPipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Reserve Id'");
+ InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpCommitWritePipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Reserve Id'");
+ InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpIsValidReserveId].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpIsValidReserveId].operands.push(OperandId, "'Reserve Id'");
InstructionDesc[OpGetNumPipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Pipe'");
+ InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpGetMaxPipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Pipe'");
+ InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpGroupReserveReadPipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Num Packets'");
+ InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpGroupReserveWritePipePackets].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Num Packets'");
+ InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpGroupCommitReadPipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Reserve Id'");
+ InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpGroupCommitWritePipe].capabilities.push_back(CapabilityPipes);
InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandScope, "'Execution'");
InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Pipe'");
InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Reserve Id'");
+ InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Size'");
+ InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Alignment'");
InstructionDesc[OpBuildNDRange].capabilities.push_back(CapabilityDeviceEnqueue);
InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkSize'");
diff --git a/SPIRV/doc.h b/SPIRV/doc.h
index c97ca85..accdd65 100755
--- a/SPIRV/doc.h
+++ b/SPIRV/doc.h
@@ -116,10 +116,9 @@
enum OperandClass {
OperandNone,
OperandId,
- OperandOptionalId,
- OperandOptionalImage,
OperandVariableIds,
OperandOptionalLiteral,
+ OperandOptionalLiteralString,
OperandVariableLiterals,
OperandVariableIdLiteral,
OperandVariableLiteralId,
@@ -168,18 +167,22 @@
class OperandParameters {
public:
OperandParameters() { }
- void push(OperandClass oc, const char* d)
+ void push(OperandClass oc, const char* d, bool opt = false)
{
opClass.push_back(oc);
desc.push_back(d);
+ optional.push_back(opt);
}
+ void setOptional();
OperandClass getClass(int op) const { return opClass[op]; }
const char* getDesc(int op) const { return desc[op]; }
+ bool isOptional(int op) const { return optional[op]; }
int getNum() const { return (int)opClass.size(); }
protected:
std::vector<OperandClass> opClass;
std::vector<const char*> desc;
+ std::vector<bool> optional;
};
// Parameterize an enumerant
@@ -240,7 +243,7 @@
int resultPresent : 1;
};
-const int OpcodeCeiling = 305;
+const int OpcodeCeiling = 320;
// The set of objects that hold all the instruction/operand
// parameterization information.
diff --git a/SPIRV/spirv.hpp b/SPIRV/spirv.hpp
index 829722e..f3d42a9 100755
--- a/SPIRV/spirv.hpp
+++ b/SPIRV/spirv.hpp
@@ -25,7 +25,6 @@
// This header is automatically generated by the same tool that creates
// the Binary Section of the SPIR-V specification.
-// Specification revision 31.
// Enumeration tokens for SPIR-V, in various styles:
// C, C++, C++11, JSON, Lua, Python
//
@@ -47,9 +46,12 @@
typedef unsigned int Id;
+#define SPV_VERSION 10000
+#define SPV_REVISION 2
+
static const unsigned int MagicNumber = 0x07230203;
-static const unsigned int Version = 99;
-static const unsigned int Revision = 31;
+static const unsigned int Version = 0x00010000;
+static const unsigned int Revision = 2;
static const unsigned int OpCodeMask = 0xffff;
static const unsigned int WordCountShift = 16;
@@ -57,7 +59,8 @@
SourceLanguageUnknown = 0,
SourceLanguageESSL = 1,
SourceLanguageGLSL = 2,
- SourceLanguageOpenCL = 3,
+ SourceLanguageOpenCL_C = 3,
+ SourceLanguageOpenCL_CPP = 4,
};
enum ExecutionModel {
@@ -96,7 +99,6 @@
ExecutionModePointMode = 10,
ExecutionModeXfb = 11,
ExecutionModeDepthReplacing = 12,
- ExecutionModeDepthAny = 13,
ExecutionModeDepthGreater = 14,
ExecutionModeDepthLess = 15,
ExecutionModeDepthUnchanged = 16,
@@ -105,10 +107,10 @@
ExecutionModeInputPoints = 19,
ExecutionModeInputLines = 20,
ExecutionModeInputLinesAdjacency = 21,
- ExecutionModeInputTriangles = 22,
+ ExecutionModeTriangles = 22,
ExecutionModeInputTrianglesAdjacency = 23,
- ExecutionModeInputQuads = 24,
- ExecutionModeInputIsolines = 25,
+ ExecutionModeQuads = 24,
+ ExecutionModeIsolines = 25,
ExecutionModeOutputVertices = 26,
ExecutionModeOutputPoints = 27,
ExecutionModeOutputLineStrip = 28,
@@ -122,11 +124,12 @@
StorageClassInput = 1,
StorageClassUniform = 2,
StorageClassOutput = 3,
- StorageClassWorkgroupLocal = 4,
- StorageClassWorkgroupGlobal = 5,
- StorageClassPrivateGlobal = 6,
+ StorageClassWorkgroup = 4,
+ StorageClassCrossWorkgroup = 5,
+ StorageClassPrivate = 6,
StorageClassFunction = 7,
StorageClassGeneric = 8,
+ StorageClassPushConstant = 9,
StorageClassAtomicCounter = 10,
StorageClassImage = 11,
};
@@ -138,6 +141,7 @@
DimCube = 3,
DimRect = 4,
DimBuffer = 5,
+ DimSubpassData = 6,
};
enum SamplerAddressingMode {
@@ -235,6 +239,7 @@
ImageChannelDataTypeHalfFloat = 13,
ImageChannelDataTypeFloat = 14,
ImageChannelDataTypeUnormInt24 = 15,
+ ImageChannelDataTypeUnormInt101010_2 = 16,
};
enum ImageOperandsShift {
@@ -245,6 +250,7 @@
ImageOperandsOffsetShift = 4,
ImageOperandsConstOffsetsShift = 5,
ImageOperandsSampleShift = 6,
+ ImageOperandsMinLodShift = 7,
};
enum ImageOperandsMask {
@@ -256,6 +262,7 @@
ImageOperandsOffsetMask = 0x00000010,
ImageOperandsConstOffsetsMask = 0x00000020,
ImageOperandsSampleMask = 0x00000040,
+ ImageOperandsMinLodMask = 0x00000080,
};
enum FPFastMathModeShift {
@@ -317,8 +324,7 @@
DecorationGLSLPacked = 9,
DecorationCPacked = 10,
DecorationBuiltIn = 11,
- DecorationSmooth = 12,
- DecorationNoperspective = 13,
+ DecorationNoPerspective = 13,
DecorationFlat = 14,
DecorationPatch = 15,
DecorationCentroid = 16,
@@ -329,10 +335,9 @@
DecorationVolatile = 21,
DecorationConstant = 22,
DecorationCoherent = 23,
- DecorationNonwritable = 24,
- DecorationNonreadable = 25,
+ DecorationNonWritable = 24,
+ DecorationNonReadable = 25,
DecorationUniform = 26,
- DecorationNoStaticUse = 27,
DecorationSaturatedConversion = 28,
DecorationStream = 29,
DecorationLocation = 30,
@@ -347,6 +352,9 @@
DecorationFPRoundingMode = 39,
DecorationFPFastMathMode = 40,
DecorationLinkageAttributes = 41,
+ DecorationNoContraction = 42,
+ DecorationInputAttachmentIndex = 43,
+ DecorationAlignment = 44,
};
enum BuiltIn {
@@ -370,7 +378,6 @@
BuiltInSampleId = 18,
BuiltInSamplePosition = 19,
BuiltInSampleMask = 20,
- BuiltInFragColor = 21,
BuiltInFragDepth = 22,
BuiltInHelperInvocation = 23,
BuiltInNumWorkgroups = 24,
@@ -384,13 +391,14 @@
BuiltInEnqueuedWorkgroupSize = 32,
BuiltInGlobalOffset = 33,
BuiltInGlobalLinearId = 34,
- BuiltInWorkgroupLinearId = 35,
BuiltInSubgroupSize = 36,
BuiltInSubgroupMaxSize = 37,
BuiltInNumSubgroups = 38,
BuiltInNumEnqueuedSubgroups = 39,
BuiltInSubgroupId = 40,
BuiltInSubgroupLocalInvocationId = 41,
+ BuiltInVertexIndex = 42,
+ BuiltInInstanceIndex = 43,
};
enum SelectionControlShift {
@@ -431,41 +439,43 @@
};
enum MemorySemanticsShift {
- MemorySemanticsRelaxedShift = 0,
- MemorySemanticsSequentiallyConsistentShift = 1,
- MemorySemanticsAcquireShift = 2,
- MemorySemanticsReleaseShift = 3,
- MemorySemanticsUniformMemoryShift = 4,
- MemorySemanticsSubgroupMemoryShift = 5,
- MemorySemanticsWorkgroupLocalMemoryShift = 6,
- MemorySemanticsWorkgroupGlobalMemoryShift = 7,
- MemorySemanticsAtomicCounterMemoryShift = 8,
- MemorySemanticsImageMemoryShift = 9,
+ MemorySemanticsAcquireShift = 1,
+ MemorySemanticsReleaseShift = 2,
+ MemorySemanticsAcquireReleaseShift = 3,
+ MemorySemanticsSequentiallyConsistentShift = 4,
+ MemorySemanticsUniformMemoryShift = 6,
+ MemorySemanticsSubgroupMemoryShift = 7,
+ MemorySemanticsWorkgroupMemoryShift = 8,
+ MemorySemanticsCrossWorkgroupMemoryShift = 9,
+ MemorySemanticsAtomicCounterMemoryShift = 10,
+ MemorySemanticsImageMemoryShift = 11,
};
enum MemorySemanticsMask {
MemorySemanticsMaskNone = 0,
- MemorySemanticsRelaxedMask = 0x00000001,
- MemorySemanticsSequentiallyConsistentMask = 0x00000002,
- MemorySemanticsAcquireMask = 0x00000004,
- MemorySemanticsReleaseMask = 0x00000008,
- MemorySemanticsUniformMemoryMask = 0x00000010,
- MemorySemanticsSubgroupMemoryMask = 0x00000020,
- MemorySemanticsWorkgroupLocalMemoryMask = 0x00000040,
- MemorySemanticsWorkgroupGlobalMemoryMask = 0x00000080,
- MemorySemanticsAtomicCounterMemoryMask = 0x00000100,
- MemorySemanticsImageMemoryMask = 0x00000200,
+ MemorySemanticsAcquireMask = 0x00000002,
+ MemorySemanticsReleaseMask = 0x00000004,
+ MemorySemanticsAcquireReleaseMask = 0x00000008,
+ MemorySemanticsSequentiallyConsistentMask = 0x00000010,
+ MemorySemanticsUniformMemoryMask = 0x00000040,
+ MemorySemanticsSubgroupMemoryMask = 0x00000080,
+ MemorySemanticsWorkgroupMemoryMask = 0x00000100,
+ MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
+ MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
+ MemorySemanticsImageMemoryMask = 0x00000800,
};
enum MemoryAccessShift {
MemoryAccessVolatileShift = 0,
MemoryAccessAlignedShift = 1,
+ MemoryAccessNontemporalShift = 2,
};
enum MemoryAccessMask {
MemoryAccessMaskNone = 0,
MemoryAccessVolatileMask = 0x00000001,
MemoryAccessAlignedMask = 0x00000002,
+ MemoryAccessNontemporalMask = 0x00000004,
};
enum Scope {
@@ -514,7 +524,6 @@
CapabilityImageBasic = 13,
CapabilityImageReadWrite = 14,
CapabilityImageMipmap = 15,
- CapabilityImageSRGBWrite = 16,
CapabilityPipes = 17,
CapabilityGroups = 18,
CapabilityDeviceEnqueue = 19,
@@ -524,7 +533,6 @@
CapabilityTessellationPointSize = 23,
CapabilityGeometryPointSize = 24,
CapabilityImageGatherExtended = 25,
- CapabilityStorageImageExtendedFormats = 26,
CapabilityStorageImageMultisample = 27,
CapabilityUniformBufferArrayDynamicIndexing = 28,
CapabilitySampledImageArrayDynamicIndexing = 29,
@@ -534,11 +542,33 @@
CapabilityCullDistance = 33,
CapabilityImageCubeArray = 34,
CapabilitySampleRateShading = 35,
+ CapabilityImageRect = 36,
+ CapabilitySampledRect = 37,
+ CapabilityGenericPointer = 38,
+ CapabilityInt8 = 39,
+ CapabilityInputAttachment = 40,
+ CapabilitySparseResidency = 41,
+ CapabilityMinLod = 42,
+ CapabilitySampled1D = 43,
+ CapabilityImage1D = 44,
+ CapabilitySampledCubeArray = 45,
+ CapabilitySampledBuffer = 46,
+ CapabilityImageBuffer = 47,
+ CapabilityImageMSArray = 48,
+ CapabilityStorageImageExtendedFormats = 49,
+ CapabilityImageQuery = 50,
+ CapabilityDerivativeControl = 51,
+ CapabilityInterpolationFunction = 52,
+ CapabilityTransformFeedback = 53,
+ CapabilityGeometryStreams = 54,
+ CapabilityStorageImageReadWithoutFormat = 55,
+ CapabilityStorageImageWriteWithoutFormat = 56,
};
enum Op {
OpNop = 0,
OpUndef = 1,
+ OpSourceContinued = 2,
OpSource = 3,
OpSourceExtension = 4,
OpName = 5,
@@ -572,6 +602,7 @@
OpTypeReserveId = 36,
OpTypeQueue = 37,
OpTypePipe = 38,
+ OpTypeForwardPointer = 39,
OpConstantTrue = 41,
OpConstantFalse = 42,
OpConstant = 43,
@@ -598,6 +629,7 @@
OpPtrAccessChain = 67,
OpArrayLength = 68,
OpGenericPtrMemSemantics = 69,
+ OpInBoundsPtrAccessChain = 70,
OpDecorate = 71,
OpMemberDecorate = 72,
OpDecorationGroup = 73,
@@ -625,7 +657,7 @@
OpImageDrefGather = 97,
OpImageRead = 98,
OpImageWrite = 99,
- OpImageQueryDim = 100,
+ OpImage = 100,
OpImageQueryFormat = 101,
OpImageQueryOrder = 102,
OpImageQuerySizeLod = 103,
@@ -674,7 +706,8 @@
OpDot = 148,
OpIAddCarry = 149,
OpISubBorrow = 150,
- OpIMulExtended = 151,
+ OpUMulExtended = 151,
+ OpSMulExtended = 152,
OpAny = 154,
OpAll = 155,
OpIsNan = 156,
@@ -769,8 +802,8 @@
OpUnreachable = 255,
OpLifetimeStart = 256,
OpLifetimeStop = 257,
- OpAsyncGroupCopy = 259,
- OpWaitGroupEvents = 260,
+ OpGroupAsyncCopy = 259,
+ OpGroupWaitEvents = 260,
OpGroupAll = 261,
OpGroupAny = 262,
OpGroupBroadcast = 263,
@@ -811,6 +844,21 @@
OpCaptureEventProfilingInfo = 302,
OpGetDefaultQueue = 303,
OpBuildNDRange = 304,
+ OpImageSparseSampleImplicitLod = 305,
+ OpImageSparseSampleExplicitLod = 306,
+ OpImageSparseSampleDrefImplicitLod = 307,
+ OpImageSparseSampleDrefExplicitLod = 308,
+ OpImageSparseSampleProjImplicitLod = 309,
+ OpImageSparseSampleProjExplicitLod = 310,
+ OpImageSparseSampleProjDrefImplicitLod = 311,
+ OpImageSparseSampleProjDrefExplicitLod = 312,
+ OpImageSparseFetch = 313,
+ OpImageSparseGather = 314,
+ OpImageSparseDrefGather = 315,
+ OpImageSparseTexelsResident = 316,
+ OpNoLine = 317,
+ OpAtomicFlagTestAndSet = 318,
+ OpAtomicFlagClear = 319,
};
// Overload operator| for mask bit combining
diff --git a/SPIRV/spvIR.h b/SPIRV/spvIR.h
index 8bf369c..6736a13 100755
--- a/SPIRV/spvIR.h
+++ b/SPIRV/spvIR.h
@@ -74,18 +74,14 @@
class Instruction {
public:
- Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), string(0) { }
- explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), string(0) { }
- virtual ~Instruction()
- {
- delete string;
- }
+ Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode) { }
+ explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode) { }
+ virtual ~Instruction() {}
void addIdOperand(Id id) { operands.push_back(id); }
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
void addStringOperand(const char* str)
{
originalString = str;
- string = new std::vector<unsigned int>;
unsigned int word;
char* wordString = (char*)&word;
char* wordPtr = wordString;
@@ -96,7 +92,7 @@
*(wordPtr++) = c;
++charCount;
if (charCount == 4) {
- string->push_back(word);
+ addImmediateOperand(word);
wordPtr = wordString;
charCount = 0;
}
@@ -107,7 +103,7 @@
// pad with 0s
for (; charCount < 4; ++charCount)
*(wordPtr++) = 0;
- string->push_back(word);
+ addImmediateOperand(word);
}
}
Op getOpCode() const { return opCode; }
@@ -128,8 +124,6 @@
if (resultId)
++wordCount;
wordCount += (unsigned int)operands.size();
- if (string)
- wordCount += (unsigned int)string->size();
// Write out the beginning of the instruction
out.push_back(((wordCount) << WordCountShift) | opCode);
@@ -141,9 +135,6 @@
// Write out the operands
for (int op = 0; op < (int)operands.size(); ++op)
out.push_back(operands[op]);
- if (string)
- for (int op = 0; op < (int)string->size(); ++op)
- out.push_back((*string)[op]);
}
protected:
@@ -152,7 +143,6 @@
Id typeId;
Op opCode;
std::vector<Id> operands;
- std::vector<unsigned int>* string; // usually non-existent
std::string originalString; // could be optimized away; convenience for getting string operand
};