Move to revision 31 of SPIR-V.
This commit is contained in:
300
SPIRV/GlslangToSpv.cpp
Normal file → Executable file
300
SPIRV/GlslangToSpv.cpp
Normal file → Executable 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)
|
||||
|
||||
Reference in New Issue
Block a user