Move to revision 31 of SPIR-V.

This commit is contained in:
John Kessenich
2015-08-06 22:53:06 -06:00
parent e24a74c320
commit 5e4b1242bf
77 changed files with 6050 additions and 5450 deletions

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

@@ -39,14 +39,17 @@
// translate them to SPIR-V.
//
#include "spirv.h"
#include "spirv.hpp"
#include "GlslangToSpv.h"
#include "SpvBuilder.h"
#include "GLSL450Lib.h"
namespace spv {
#include "GLSL.std.450.h"
}
// Glslang includes
#include "../glslang/MachineIndependent/localintermediate.h"
#include "../glslang/MachineIndependent/SymbolTable.h"
#include "../glslang/Include/Common.h"
#include <string>
#include <map>
@@ -85,6 +88,7 @@ protected:
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
spv::Id getSampledType(const glslang::TSampler&);
spv::Id convertGlslangToSpvType(const glslang::TType& type);
void updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset);
bool isShaderEntrypoint(const glslang::TIntermAggregate* node);
void makeFunctions(const glslang::TIntermSequence&);
@@ -93,6 +97,7 @@ protected:
void handleFunctionEntry(const glslang::TIntermAggregate* node);
void translateArguments(const glslang::TIntermSequence& glslangArguments, std::vector<spv::Id>& arguments);
spv::Id handleBuiltInFunctionCall(const glslang::TIntermAggregate*);
spv::Id handleTextureCall(spv::Decoration precision, glslang::TOperator, spv::Id typeId, glslang::TSampler, std::vector<spv::Id>& idArguments);
spv::Id handleUserFunctionCall(const glslang::TIntermAggregate*);
spv::Id createBinaryOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, spv::Id left, spv::Id right, glslang::TBasicType typeProxy, bool reduceComparison = true);
@@ -100,7 +105,7 @@ protected:
spv::Id createConversion(glslang::TOperator op, spv::Decoration precision, spv::Id destTypeId, spv::Id operand);
spv::Id makeSmearedConstant(spv::Id constant, int vectorSize);
spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands);
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands);
spv::Id createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy);
spv::Id createNoArgOperation(glslang::TOperator op);
spv::Id getSymbolId(const glslang::TIntermSymbol* node);
void addDecoration(spv::Id id, spv::Decoration dec);
@@ -208,9 +213,9 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler)
spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
{
switch (type.getQualifier().precision) {
case glslang::EpqLow: return spv::DecorationPrecisionLow;
case glslang::EpqMedium: return spv::DecorationPrecisionMedium;
case glslang::EpqHigh: return spv::DecorationPrecisionHigh;
case glslang::EpqLow: return spv::DecorationRelaxedPrecision; // TODO: Map instead to 16-bit types?
case glslang::EpqMedium: return spv::DecorationRelaxedPrecision;
case glslang::EpqHigh: return spv::NoPrecision;
default:
return spv::NoPrecision;
}
@@ -255,12 +260,9 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type)
case glslang::EvqBuffer:
switch (type.getQualifier().layoutPacking) {
case glslang::ElpShared: return spv::DecorationGLSLShared;
case glslang::ElpStd140: return spv::DecorationGLSLStd140;
case glslang::ElpStd430: return spv::DecorationGLSLStd430;
case glslang::ElpPacked: return spv::DecorationGLSLPacked;
default:
spv::MissingFunctionality("uniform block layout");
return spv::DecorationGLSLShared;
return (spv::Decoration)spv::BadValue;
}
case glslang::EvqVaryingIn:
case glslang::EvqVaryingOut:
@@ -309,7 +311,6 @@ spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable builtIn)
switch (builtIn) {
case glslang::EbvPosition: return spv::BuiltInPosition;
case glslang::EbvPointSize: return spv::BuiltInPointSize;
case glslang::EbvClipVertex: return spv::BuiltInClipVertex;
case glslang::EbvClipDistance: return spv::BuiltInClipDistance;
case glslang::EbvCullDistance: return spv::BuiltInCullDistance;
case glslang::EbvVertexId: return spv::BuiltInVertexId;
@@ -359,7 +360,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
stdBuiltins = builder.import("GLSL.std.450");
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
shaderEntry = builder.makeMain();
builder.addEntryPoint(executionModel, shaderEntry);
builder.addEntryPoint(executionModel, shaderEntry, "main");
// Add the source extensions
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
@@ -374,13 +375,16 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
unsigned int mode;
switch (glslangIntermediate->getStage()) {
case EShLangVertex:
builder.addCapability(spv::CapabilityShader);
break;
case EShLangTessControl:
builder.addCapability(spv::CapabilityTessellation);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices());
break;
case EShLangTessEvaluation:
builder.addCapability(spv::CapabilityTessellation);
switch (glslangIntermediate->getInputPrimitive()) {
case glslang::ElgTriangles: mode = spv::ExecutionModeInputTriangles; break;
case glslang::ElgQuads: mode = spv::ExecutionModeInputQuads; break;
@@ -397,6 +401,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
break;
case EShLangGeometry:
builder.addCapability(spv::CapabilityGeometry);
switch (glslangIntermediate->getInputPrimitive()) {
case glslang::ElgPoints: mode = spv::ExecutionModeInputPoints; break;
case glslang::ElgLines: mode = spv::ExecutionModeInputLines; break;
@@ -421,13 +426,17 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* gls
break;
case EShLangFragment:
builder.addCapability(spv::CapabilityShader);
if (glslangIntermediate->getPixelCenterInteger())
builder.addExecutionMode(shaderEntry, spv::ExecutionModePixelCenterInteger);
if (glslangIntermediate->getOriginUpperLeft())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginUpperLeft);
else
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOriginLowerLeft);
break;
case EShLangCompute:
builder.addCapability(spv::CapabilityShader);
break;
default:
@@ -1051,7 +1060,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
result = createUnaryOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands.front(), node->getType().getBasicType() == glslang::EbtFloat || node->getType().getBasicType() == glslang::EbtDouble);
break;
default:
result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands);
result = createMiscOperation(node->getOp(), precision, convertGlslangToSpvType(node->getType()), operands, node->getBasicType());
break;
}
}
@@ -1311,9 +1320,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
case glslang::EbtSampler:
{
const glslang::TSampler& sampler = type.getSampler();
spvType = builder.makeSampler(getSampledType(sampler), TranslateDimensionality(sampler),
sampler.image ? spv::Builder::samplerContentImage : spv::Builder::samplerContentTextureFilter,
sampler.arrayed, sampler.shadow, sampler.ms);
spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.shadow, sampler.arrayed, sampler.ms,
sampler.image ? 2 : 1, spv::ImageFormatUnknown); // TODO: translate format, needed for GLSL image ops
// OpenGL "textures" need to be combined with a sampler
if (! sampler.image)
spvType = builder.makeSampledImageType(spvType);
}
break;
case glslang::EbtStruct:
@@ -1350,6 +1361,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
structMap[glslangStruct] = spvType;
// Name and decorate the non-hidden members
int offset = -1;
for (int i = 0; i < (int)glslangStruct->size(); i++) {
glslang::TType& glslangType = *(*glslangStruct)[i].type;
int member = i;
@@ -1368,6 +1380,14 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent);
if (glslangType.getQualifier().hasXfbOffset())
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutXfbOffset);
else {
// figure out what to do with offset, which is accumulating
int nextOffset;
updateMemberOffset(type, glslangType, offset, nextOffset);
if (offset >= 0)
builder.addMemberDecoration(spvType, member, spv::DecorationOffset, glslangType.getQualifier().layoutOffset);
offset = nextOffset;
}
// built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(glslangType.getQualifier().builtIn);
@@ -1383,7 +1403,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
if (glslangIntermediate->getXfbMode()) {
if (type.getQualifier().hasXfbStride())
builder.addDecoration(spvType, spv::DecorationStride, type.getQualifier().layoutXfbStride);
builder.addDecoration(spvType, spv::DecorationXfbStride, type.getQualifier().layoutXfbStride);
if (type.getQualifier().hasXfbBuffer())
builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer);
}
@@ -1415,6 +1435,49 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
return spvType;
}
// Given a member type of a struct, realign the current offset for it, and compute
// the next (not yet aligned) offset for the next member, which will get aligned
// on the next call.
// 'currentOffset' should be passed in already initialized, ready to modify, and reflecting
// the migration of data from nextOffset -> currentOffset. It should be -1 on the first call.
// -1 means a non-forced member offset (no decoration needed).
void TGlslangToSpvTraverser::updateMemberOffset(const glslang::TType& structType, const glslang::TType& memberType, int& currentOffset, int& nextOffset)
{
// this will get a positive value when deemed necessary
nextOffset = -1;
bool forceOffset = structType.getQualifier().layoutPacking == glslang::ElpStd140 ||
structType.getQualifier().layoutPacking == glslang::ElpStd430;
// override anything in currentOffset with user-set offset
if (memberType.getQualifier().hasOffset())
currentOffset = memberType.getQualifier().layoutOffset;
// It could be that current linker usage in glslang updated all the layoutOffset,
// in which case the following code does not matter. But, that's not quite right
// once cross-compilation unit GLSL validation is done, as the original user
// settings are needed in layoutOffset, and then the following will come into play.
if (! forceOffset) {
if (! memberType.getQualifier().hasOffset())
currentOffset = -1;
return;
}
// Getting this far means we are forcing offsets
if (currentOffset < 0)
currentOffset = 0;
// Now, currentOffset is valid (either 0, or from a previous nextOffset),
// but possibly not yet correctly aligned.
int memberSize;
int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, memberType.getQualifier().layoutPacking == glslang::ElpStd140);
glslang::RoundToPow2(currentOffset, memberAlignment);
nextOffset = currentOffset + memberSize;
}
bool TGlslangToSpvTraverser::isShaderEntrypoint(const glslang::TIntermAggregate* node)
{
return node->getName() == "main(";
@@ -1519,11 +1582,6 @@ spv::Id TGlslangToSpvTraverser::handleBuiltInFunctionCall(const glslang::TInterm
{
std::vector<spv::Id> arguments;
translateArguments(node->getSequence(), arguments);
std::vector<spv::Id> argTypes;
for (int a = 0; a < (int)arguments.size(); ++a)
argTypes.push_back(builder.getTypeId(arguments[a]));
spv::Decoration precision = TranslatePrecisionDecoration(node->getType());
if (node->getName() == "ftransform(") {
@@ -1544,22 +1602,22 @@ spv::Id TGlslangToSpvTraverser::handleBuiltInFunctionCall(const glslang::TInterm
if (node->getName().find("textureSize", 0) != std::string::npos) {
if (arguments.size() > 1) {
params.lod = arguments[1];
return builder.createTextureQueryCall(spv::OpTextureQuerySizeLod, params);
return builder.createTextureQueryCall(spv::OpImageQuerySizeLod, params);
} else
return builder.createTextureQueryCall(spv::OpTextureQuerySize, params);
return builder.createTextureQueryCall(spv::OpImageQuerySize, params);
}
// special case the number of samples query
if (node->getName().find("textureSamples", 0) != std::string::npos)
return builder.createTextureQueryCall(spv::OpTextureQuerySamples, params);
return builder.createTextureQueryCall(spv::OpImageQuerySamples, params);
// special case the other queries
if (node->getName().find("Query", 0) != std::string::npos) {
if (node->getName().find("Levels", 0) != std::string::npos)
return builder.createTextureQueryCall(spv::OpTextureQueryLevels, params);
return builder.createTextureQueryCall(spv::OpImageQueryLevels, params);
else if (node->getName().find("Lod", 0) != std::string::npos) {
params.coords = arguments[1];
return builder.createTextureQueryCall(spv::OpTextureQueryLod, params);
return builder.createTextureQueryCall(spv::OpImageQueryLod, params);
} else
spv::MissingFunctionality("glslang texture query");
}
@@ -1599,6 +1657,16 @@ spv::Id TGlslangToSpvTraverser::handleBuiltInFunctionCall(const glslang::TInterm
int extraArgs = 0;
if (cubeCompare)
params.Dref = arguments[2];
else if (sampler.shadow) {
std::vector<spv::Id> indexes;
int comp;
if (proj)
comp = 3;
else
comp = builder.getNumComponents(params.coords) - 1;
indexes.push_back(comp);
params.Dref = builder.createCompositeExtract(params.coords, builder.getScalarTypeId(builder.getTypeId(params.coords)), indexes);
}
if (lod) {
params.lod = arguments[2];
++extraArgs;
@@ -1835,7 +1903,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, spv
break;
case glslang::EOpLogicalXor:
needMatchingVectors = false;
binOp = spv::OpLogicalXor;
binOp = spv::OpLogicalNotEqual;
break;
case glslang::EOpLessThan:
@@ -1974,107 +2042,109 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
case glslang::EOpLogicalNot:
case glslang::EOpVectorLogicalNot:
unaryOp = spv::OpLogicalNot;
break;
case glslang::EOpBitwiseNot:
unaryOp = spv::OpNot;
break;
case glslang::EOpDeterminant:
libCall = GLSL_STD_450::Determinant;
libCall = spv::GLSLstd450Determinant;
break;
case glslang::EOpMatrixInverse:
libCall = GLSL_STD_450::MatrixInverse;
libCall = spv::GLSLstd450MatrixInverse;
break;
case glslang::EOpTranspose:
unaryOp = spv::OpTranspose;
break;
case glslang::EOpRadians:
libCall = GLSL_STD_450::Radians;
libCall = spv::GLSLstd450Radians;
break;
case glslang::EOpDegrees:
libCall = GLSL_STD_450::Degrees;
libCall = spv::GLSLstd450Degrees;
break;
case glslang::EOpSin:
libCall = GLSL_STD_450::Sin;
libCall = spv::GLSLstd450Sin;
break;
case glslang::EOpCos:
libCall = GLSL_STD_450::Cos;
libCall = spv::GLSLstd450Cos;
break;
case glslang::EOpTan:
libCall = GLSL_STD_450::Tan;
libCall = spv::GLSLstd450Tan;
break;
case glslang::EOpAcos:
libCall = GLSL_STD_450::Acos;
libCall = spv::GLSLstd450Acos;
break;
case glslang::EOpAsin:
libCall = GLSL_STD_450::Asin;
libCall = spv::GLSLstd450Asin;
break;
case glslang::EOpAtan:
libCall = GLSL_STD_450::Atan;
libCall = spv::GLSLstd450Atan;
break;
case glslang::EOpAcosh:
libCall = GLSL_STD_450::Acosh;
libCall = spv::GLSLstd450Acosh;
break;
case glslang::EOpAsinh:
libCall = GLSL_STD_450::Asinh;
libCall = spv::GLSLstd450Asinh;
break;
case glslang::EOpAtanh:
libCall = GLSL_STD_450::Atanh;
libCall = spv::GLSLstd450Atanh;
break;
case glslang::EOpTanh:
libCall = GLSL_STD_450::Tanh;
libCall = spv::GLSLstd450Tanh;
break;
case glslang::EOpCosh:
libCall = GLSL_STD_450::Cosh;
libCall = spv::GLSLstd450Cosh;
break;
case glslang::EOpSinh:
libCall = GLSL_STD_450::Sinh;
libCall = spv::GLSLstd450Sinh;
break;
case glslang::EOpLength:
libCall = GLSL_STD_450::Length;
libCall = spv::GLSLstd450Length;
break;
case glslang::EOpNormalize:
libCall = GLSL_STD_450::Normalize;
libCall = spv::GLSLstd450Normalize;
break;
case glslang::EOpExp:
libCall = GLSL_STD_450::Exp;
libCall = spv::GLSLstd450Exp;
break;
case glslang::EOpLog:
libCall = GLSL_STD_450::Log;
libCall = spv::GLSLstd450Log;
break;
case glslang::EOpExp2:
libCall = GLSL_STD_450::Exp2;
libCall = spv::GLSLstd450Exp2;
break;
case glslang::EOpLog2:
libCall = GLSL_STD_450::Log2;
libCall = spv::GLSLstd450Log2;
break;
case glslang::EOpSqrt:
libCall = GLSL_STD_450::Sqrt;
libCall = spv::GLSLstd450Sqrt;
break;
case glslang::EOpInverseSqrt:
libCall = GLSL_STD_450::InverseSqrt;
libCall = spv::GLSLstd450InverseSqrt;
break;
case glslang::EOpFloor:
libCall = GLSL_STD_450::Floor;
libCall = spv::GLSLstd450Floor;
break;
case glslang::EOpTrunc:
libCall = GLSL_STD_450::Trunc;
libCall = spv::GLSLstd450Trunc;
break;
case glslang::EOpRound:
libCall = GLSL_STD_450::Round;
libCall = spv::GLSLstd450Round;
break;
case glslang::EOpRoundEven:
libCall = GLSL_STD_450::RoundEven;
libCall = spv::GLSLstd450RoundEven;
break;
case glslang::EOpCeil:
libCall = GLSL_STD_450::Ceil;
libCall = spv::GLSLstd450Ceil;
break;
case glslang::EOpFract:
libCall = GLSL_STD_450::Fract;
libCall = spv::GLSLstd450Fract;
break;
case glslang::EOpIsNan:
@@ -2084,35 +2154,23 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
unaryOp = spv::OpIsInf;
break;
case glslang::EOpFloatBitsToInt:
libCall = GLSL_STD_450::FloatBitsToInt;
break;
case glslang::EOpFloatBitsToUint:
libCall = GLSL_STD_450::FloatBitsToUint;
break;
case glslang::EOpIntBitsToFloat:
libCall = GLSL_STD_450::IntBitsToFloat;
break;
case glslang::EOpUintBitsToFloat:
libCall = GLSL_STD_450::UintBitsToFloat;
break;
case glslang::EOpPackSnorm2x16:
libCall = GLSL_STD_450::PackSnorm2x16;
libCall = spv::GLSLstd450PackSnorm2x16;
break;
case glslang::EOpUnpackSnorm2x16:
libCall = GLSL_STD_450::UnpackSnorm2x16;
libCall = spv::GLSLstd450UnpackSnorm2x16;
break;
case glslang::EOpPackUnorm2x16:
libCall = GLSL_STD_450::PackUnorm2x16;
libCall = spv::GLSLstd450PackUnorm2x16;
break;
case glslang::EOpUnpackUnorm2x16:
libCall = GLSL_STD_450::UnpackUnorm2x16;
libCall = spv::GLSLstd450UnpackUnorm2x16;
break;
case glslang::EOpPackHalf2x16:
libCall = GLSL_STD_450::PackHalf2x16;
libCall = spv::GLSLstd450PackHalf2x16;
break;
case glslang::EOpUnpackHalf2x16:
libCall = GLSL_STD_450::UnpackHalf2x16;
libCall = spv::GLSLstd450UnpackHalf2x16;
break;
case glslang::EOpDPdx:
@@ -2151,10 +2209,16 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, spv:
break;
case glslang::EOpAbs:
libCall = GLSL_STD_450::Abs;
if (isFloat)
libCall = spv::GLSLstd450FAbs;
else
libCall = spv::GLSLstd450SAbs;
break;
case glslang::EOpSign:
libCall = GLSL_STD_450::Sign;
if (isFloat)
libCall = spv::GLSLstd450FSign;
else
libCall = spv::GLSLstd450SSign;
break;
default:
@@ -2291,10 +2355,10 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
opCode = spv::OpAtomicIAdd;
break;
case glslang::EOpAtomicMin:
opCode = spv::OpAtomicIMin;
opCode = spv::OpAtomicSMin;
break;
case glslang::EOpAtomicMax:
opCode = spv::OpAtomicIMax;
opCode = spv::OpAtomicSMax;
break;
case glslang::EOpAtomicAnd:
opCode = spv::OpAtomicAnd;
@@ -2331,8 +2395,8 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
auto opIt = operands.begin(); // walk the glslang operands
spvAtomicOperands.push_back(*(opIt++));
spvAtomicOperands.push_back(spv::ExecutionScopeDevice); // TBD: what is the correct scope?
spvAtomicOperands.push_back( spv::MemorySemanticsMaskNone); // TBD: what are the correct memory semantics?
spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope?
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
// Add the rest of the operands, skipping the first one, which was dealt with above.
// For some ops, there are none, for some 1, for compare-exchange, 2.
@@ -2342,58 +2406,76 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
return builder.createOp(opCode, typeId, spvAtomicOperands);
}
spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands)
spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
bool isUnsigned = typeProxy == glslang::EbtUint;
bool isFloat = typeProxy == glslang::EbtFloat || typeProxy == glslang::EbtDouble;
spv::Op opCode = spv::OpNop;
int libCall = -1;
switch (op) {
case glslang::EOpMin:
libCall = GLSL_STD_450::Min;
if (isFloat)
libCall = spv::GLSLstd450FMin;
else if (isUnsigned)
libCall = spv::GLSLstd450UMin;
else
libCall = spv::GLSLstd450SMin;
break;
case glslang::EOpModf:
libCall = GLSL_STD_450::Modf;
libCall = spv::GLSLstd450Modf;
break;
case glslang::EOpMax:
libCall = GLSL_STD_450::Max;
if (isFloat)
libCall = spv::GLSLstd450FMax;
else if (isUnsigned)
libCall = spv::GLSLstd450UMax;
else
libCall = spv::GLSLstd450SMax;
break;
case glslang::EOpPow:
libCall = GLSL_STD_450::Pow;
libCall = spv::GLSLstd450Pow;
break;
case glslang::EOpDot:
opCode = spv::OpDot;
break;
case glslang::EOpAtan:
libCall = GLSL_STD_450::Atan2;
libCall = spv::GLSLstd450Atan2;
break;
case glslang::EOpClamp:
libCall = GLSL_STD_450::Clamp;
if (isFloat)
libCall = spv::GLSLstd450FClamp;
else if (isUnsigned)
libCall = spv::GLSLstd450UClamp;
else
libCall = spv::GLSLstd450SClamp;
break;
case glslang::EOpMix:
libCall = GLSL_STD_450::Mix;
libCall = spv::GLSLstd450Mix;
break;
case glslang::EOpStep:
libCall = GLSL_STD_450::Step;
libCall = spv::GLSLstd450Step;
break;
case glslang::EOpSmoothStep:
libCall = GLSL_STD_450::SmoothStep;
libCall = spv::GLSLstd450SmoothStep;
break;
case glslang::EOpDistance:
libCall = GLSL_STD_450::Distance;
libCall = spv::GLSLstd450Distance;
break;
case glslang::EOpCross:
libCall = GLSL_STD_450::Cross;
libCall = spv::GLSLstd450Cross;
break;
case glslang::EOpFaceForward:
libCall = GLSL_STD_450::FaceForward;
libCall = spv::GLSLstd450FaceForward;
break;
case glslang::EOpReflect:
libCall = GLSL_STD_450::Reflect;
libCall = spv::GLSLstd450Reflect;
break;
case glslang::EOpRefract:
libCall = GLSL_STD_450::Refract;
libCall = spv::GLSLstd450Refract;
break;
default:
@@ -2444,26 +2526,26 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op)
builder.createNoResultOp(spv::OpEndPrimitive);
return 0;
case glslang::EOpBarrier:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
builder.createControlBarrier(spv::ExecutionScopeDevice);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory);
builder.createControlBarrier(spv::ScopeDevice, spv::ScopeDevice, spv::MemorySemanticsMaskNone);
return 0;
case glslang::EOpMemoryBarrier:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAllMemory);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory);
return 0;
case glslang::EOpMemoryBarrierAtomicCounter:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask);
return 0;
case glslang::EOpMemoryBarrierBuffer:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsUniformMemoryMask);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask);
return 0;
case glslang::EOpMemoryBarrierImage:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsImageMemoryMask);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask);
return 0;
case glslang::EOpMemoryBarrierShared:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupLocalMemoryMask);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupLocalMemoryMask);
return 0;
case glslang::EOpGroupMemoryBarrier:
builder.createMemoryBarrier(spv::ExecutionScopeDevice, spv::MemorySemanticsWorkgroupGlobalMemoryMask);
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupGlobalMemoryMask);
return 0;
default:
spv::MissingFunctionality("operation with no arguments");
@@ -2495,7 +2577,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
if (glslangIntermediate->getXfbMode()) {
if (symbol->getQualifier().hasXfbStride())
builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
if (symbol->getQualifier().hasXfbBuffer())
builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
if (symbol->getQualifier().hasXfbOffset())
@@ -2512,14 +2594,14 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, spv::DecorationBinding, symbol->getQualifier().layoutBinding);
if (glslangIntermediate->getXfbMode()) {
if (symbol->getQualifier().hasXfbStride())
builder.addDecoration(id, spv::DecorationStride, symbol->getQualifier().layoutXfbStride);
builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride);
if (symbol->getQualifier().hasXfbBuffer())
builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer);
}
// built-in variable decorations
spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn);
if ((unsigned int)builtIn != spv::BadValue)
if (builtIn != spv::BadValue)
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
if (linkageOnly)