Add lerp, fix sincos return type, ret type tests, non-square mats, HLSL->AST tx semantics

This commit is contained in:
LoopDawg
2016-06-20 13:26:59 -06:00
parent a4a4d5e22c
commit 4624a02e21
9 changed files with 9098 additions and 5755 deletions

View File

@@ -799,6 +799,68 @@ TOperator HlslParseContext::mapAtomicOp(const TSourceLoc& loc, TOperator op, boo
}
}
//
// Change texture parameters to match AST & SPIR-V semantics
//
void HlslParseContext::textureParameters(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments)
{
if (!node || !node->getAsOperator())
return;
const TOperator op = node->getAsOperator()->getOp();
const TIntermAggregate* argAggregate = arguments ? arguments->getAsAggregate() : nullptr;
switch (op) {
case EOpTexture:
{
// Texture with ddx & ddy is really gradient form
if (argAggregate->getSequence().size() == 4) {
node->getAsAggregate()->setOperator(EOpTextureGrad);
break;
}
break;
}
case EOpTextureBias:
{
TIntermTyped* arg0 = argAggregate->getSequence()[0]->getAsTyped(); // sampler
TIntermTyped* arg1 = argAggregate->getSequence()[1]->getAsTyped(); // coord
// HLSL puts bias in W component of coordinate. We extract it and add it to
// the argument list, instead
TIntermTyped* w = intermediate.addConstantUnion(3, loc, true);
TIntermTyped* bias = intermediate.addIndex(EOpIndexDirect, arg1, w, loc);
TOperator constructOp = EOpNull;
switch (arg0->getType().getSampler().dim) {
case Esd1D: constructOp = EOpConstructFloat; break; // 1D
case Esd2D: constructOp = EOpConstructVec2; break; // 2D
case Esd3D: constructOp = EOpConstructVec3; break; // 3D
case EsdCube: constructOp = EOpConstructVec3; break; // also 3D
default: break;
}
TIntermAggregate* constructCoord = new TIntermAggregate(constructOp);
constructCoord->getSequence().push_back(arg1);
constructCoord->setLoc(loc);
TIntermAggregate* tex = new TIntermAggregate(EOpTexture);
tex->getSequence().push_back(arg0); // sampler
tex->getSequence().push_back(constructCoord); // coordinate
tex->getSequence().push_back(bias); // bias
tex->setLoc(loc);
node = tex;
break;
}
default:
break; // most pass through unchanged
}
}
//
// Optionally decompose intrinsics to AST opcodes.
//
void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*& node, TIntermNode* arguments)
@@ -875,6 +937,7 @@ void HlslParseContext::decomposeIntrinsic(const TSourceLoc& loc, TIntermTyped*&
compoundStatement = intermediate.growAggregate(compoundStatement, cosAssign);
compoundStatement->setOperator(EOpSequence);
compoundStatement->setLoc(loc);
compoundStatement->setType(TType(EbtVoid));
node = compoundStatement;
@@ -1222,6 +1285,7 @@ TIntermTyped* HlslParseContext::handleFunctionCall(const TSourceLoc& loc, TFunct
}
decomposeIntrinsic(loc, result, arguments);
textureParameters(loc, result, arguments);
}
}

View File

@@ -87,6 +87,7 @@ public:
void handleFunctionArgument(TFunction*, TIntermTyped*& arguments, TIntermTyped* newArg);
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void textureParameters(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
TIntermTyped* handleLengthMethod(const TSourceLoc&, TFunction*, TIntermNode*);
void addInputArgumentConversions(const TFunction&, TIntermNode*&) const;
TIntermTyped* addOutputArgumentConversions(const TFunction&, TIntermAggregate&) const;

View File

@@ -54,6 +54,8 @@
namespace { // anonymous namespace functions
const bool UseHlslTypes = false;
const char* BaseTypeName(const char* argOrder, const char* scalarName, const char* vecName, const char* matName)
{
switch (*argOrder) {
@@ -74,22 +76,38 @@ const char* BaseTypeName(const char* argOrder, const char* scalarName, const cha
glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, const char* argType, int dim0, int dim1)
{
const bool transpose = (argOrder[0] == '^');
const bool matMul = (argOrder[0] == '#');
// Take transpose of matrix dimensions
if (transpose) {
std::swap(dim0, dim1);
if (transpose) { // Take transpose of matrix dimensions
std::swap(dim0, dim1);
++argOrder;
} else if (matMul) {
dim0 = dim1; // set vector dimension to mat col
++argOrder;
}
switch (*argType) {
case '-': s += "void"; break;
case 'F': s += BaseTypeName(argOrder, "float", "vec", "mat"); break;
case 'D': s += BaseTypeName(argOrder, "double", "dvec", "dmat"); break;
case 'I': s += BaseTypeName(argOrder, "int", "ivec", "imat"); break;
case 'U': s += BaseTypeName(argOrder, "uint", "uvec", "umat"); break;
case 'B': s += BaseTypeName(argOrder, "bool", "bvec", "bmat"); break;
case 'S': s += BaseTypeName(argOrder, "sampler", "sampler", "sampler"); break; // TODO:
default: s += "UNKNOWN_TYPE"; break;
if (UseHlslTypes) {
switch (*argType) {
case '-': s += "void"; break;
case 'F': s += "float"; break;
case 'D': s += "double"; break;
case 'I': s += "int"; break;
case 'U': s += "uint"; break;
case 'B': s += "bool"; break;
case 'S': s += "sampler"; break;
default: s += "UNKNOWN_TYPE"; break;
}
} else {
switch (*argType) {
case '-': s += "void"; break;
case 'F': s += BaseTypeName(argOrder, "float", "vec", "mat"); break;
case 'D': s += BaseTypeName(argOrder, "double", "dvec", "dmat"); break;
case 'I': s += BaseTypeName(argOrder, "int", "ivec", "imat"); break;
case 'U': s += BaseTypeName(argOrder, "uint", "uvec", "umat"); break;
case 'B': s += BaseTypeName(argOrder, "bool", "bvec", "bmat"); break;
case 'S': s += BaseTypeName(argOrder, "sampler", "sampler", "sampler"); break; // TODO:
default: s += "UNKNOWN_TYPE"; break;
}
}
// handle fixed vector sizes, such as float3, and only ever 3.
@@ -119,7 +137,13 @@ glslang::TString& AppendTypeName(glslang::TString& s, const char* argOrder, cons
case '-': break; // no dimensions for voids
case 'S': break; // no dimensions on scalars
case 'V': s += ('0' + dim0); break;
case 'M': s += ('0' + dim0); s += 'x'; s += ('0' + dim1); break;
case 'M':
{
if (!UseHlslTypes) // GLSL has column first for mat types
std::swap(dim0, dim1);
s += ('0' + dim0); s += 'x'; s += ('0' + dim1);
break;
}
}
return s;
@@ -142,7 +166,7 @@ inline bool IsValidGlsl(const char* cname, char retOrder, char retType, char arg
const std::string name(cname); // for ease of comparison. slow, but temporary, until HLSL parser is online.
if (isMat && dim0 != dim1) // TODO: avoid mats until we find the right GLSL profile
if (isMat && dim1 == 1) // TODO: avoid mat Nx1 until we find the right GLSL profile
return false;
if (isMat && (argType == 'I' || argType == 'U' || argType == 'B') ||
@@ -210,6 +234,39 @@ TBuiltInParseablesHlsl::TBuiltInParseablesHlsl()
{
}
//
// Handle creation of mat*mat specially, since it doesn't fall conveniently out of
// the generic prototype creation code below.
//
void TBuiltInParseablesHlsl::createMatTimesMat()
{
TString& s = commonBuiltins;
const int first = (UseHlslTypes ? 1 : 2);
for (int xRows = first; xRows <=4; xRows++) {
for (int xCols = first; xCols <=4; xCols++) {
const int yRows = xCols;
for (int yCols = first; yCols <=4; yCols++) {
const int retRows = xRows;
const int retCols = yCols;
AppendTypeName(s, "M", "F", retRows, retCols); // add return type
s.append(" "); // space between type and name
s.append("mul"); // intrinsic name
s.append("("); // open paren
AppendTypeName(s, "M", "F", xRows, xCols); // add X input
s.append(", ");
AppendTypeName(s, "M", "F", yRows, yCols); // add Y input
s.append(");\n"); // close paren
}
}
}
}
//
// Add all context-independent built-in functions and variables that are present
// for the given version and profile. Share common ones across stages, otherwise
@@ -232,6 +289,7 @@ void TBuiltInParseablesHlsl::initialize(int version, EProfile profile, const Spv
// '>' as first letter of order creates an output parameter
// '<' as first letter of order creates an input parameter
// '^' as first letter of order takes transpose dimensions
// '#' as first letter of order sets rows=cols for mats
static const struct {
const char* name; // intrinsic name
@@ -321,6 +379,7 @@ void TBuiltInParseablesHlsl::initialize(int version, EProfile profile, const Spv
{ "isnan", nullptr, "B" , "SVM", "F", EShLangAll },
{ "ldexp", nullptr, nullptr, "SVM,", "F,", EShLangAll },
{ "length", "S", "F", "V", "F", EShLangAll },
{ "lerp", nullptr, nullptr, "SVM,,", "F,,", EShLangAll },
{ "lit", "V4", "F", "S,,", "F,,", EShLangAll },
{ "log", nullptr, nullptr, "SVM", "F", EShLangAll },
{ "log10", nullptr, nullptr, "SVM", "F", EShLangAll },
@@ -330,16 +389,15 @@ void TBuiltInParseablesHlsl::initialize(int version, EProfile profile, const Spv
{ "min", nullptr, nullptr, "SVM,", "FI,", EShLangAll },
{ "modf", nullptr, nullptr, "SVM,>", "FI,", EShLangAll },
{ "msad4", "V4", "U", "S,V2,V4", "U,,", EShLangAll },
// TODO: fix matrix return size for non-square mats used with mul opcode
{ "mul", "S", nullptr, "S,S", "FI,", EShLangAll },
{ "mul", "V", nullptr, "S,V", "FI,", EShLangAll },
{ "mul", "M", nullptr, "S,M", "FI,", EShLangAll },
{ "mul", "V", nullptr, "V,S", "FI,", EShLangAll },
{ "mul", "S", nullptr, "V,V", "FI,", EShLangAll },
{ "mul", "V", nullptr, "V,M", "FI,", EShLangAll },
{ "mul", "#V", nullptr, "V,M", "FI,", EShLangAll },
{ "mul", "M", nullptr, "M,S", "FI,", EShLangAll },
{ "mul", "V", nullptr, "M,V", "FI,", EShLangAll },
{ "mul", "M", nullptr, "M,M", "FI,", EShLangAll },
{ "mul", "V", nullptr, "M,#V", "FI,", EShLangAll },
// mat*mat form of mul is handled in createMatTimesMat()
{ "noise", "S", "F", "V", "F", EShLangFragmentMask },
{ "normalize", nullptr, nullptr, "V", "F", EShLangAll },
{ "pow", nullptr, nullptr, "SVM,", "F,", EShLangAll },
@@ -465,7 +523,7 @@ void TBuiltInParseablesHlsl::initialize(int version, EProfile profile, const Spv
if (*nthArgOrder == ',' || *nthArgOrder == '\0') nthArgOrder = argOrder;
if (*nthArgType == ',' || *nthArgType == '\0') nthArgType = argType;
AppendTypeName(s, nthArgOrder, nthArgType, dim0, dim1); // Add first argument
AppendTypeName(s, nthArgOrder, nthArgType, dim0, dim1); // Add arguments
}
s.append(");\n"); // close paren and trailing semicolon
@@ -482,6 +540,8 @@ void TBuiltInParseablesHlsl::initialize(int version, EProfile profile, const Spv
}
}
createMatTimesMat(); // handle this case separately, for convenience
// printf("Common:\n%s\n", getCommonString().c_str());
// printf("Frag:\n%s\n", getStageString(EShLangFragment).c_str());
// printf("Vertex:\n%s\n", getStageString(EShLangVertex).c_str());
@@ -586,6 +646,7 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int version, EProfile profile, con
symbolTable.relateToOperator("isnan", EOpIsNan);
symbolTable.relateToOperator("ldexp", EOpLdexp);
symbolTable.relateToOperator("length", EOpLength);
symbolTable.relateToOperator("lerp", EOpMix);
symbolTable.relateToOperator("lit", EOpLit);
symbolTable.relateToOperator("log", EOpLog);
symbolTable.relateToOperator("log10", EOpLog10);
@@ -628,25 +689,25 @@ void TBuiltInParseablesHlsl::identifyBuiltIns(int version, EProfile profile, con
symbolTable.relateToOperator("tan", EOpTan);
symbolTable.relateToOperator("tanh", EOpTanh);
symbolTable.relateToOperator("tex1D", EOpTexture);
// symbolTable.relateToOperator("tex1Dbias", // TODO:
symbolTable.relateToOperator("tex1Dbias", EOpTextureBias);
symbolTable.relateToOperator("tex1Dgrad", EOpTextureGrad);
symbolTable.relateToOperator("tex1Dlod", EOpTextureLod);
symbolTable.relateToOperator("tex1Dproj", EOpTextureProj);
symbolTable.relateToOperator("tex2D", EOpTexture);
// symbolTable.relateToOperator("tex2Dbias", // TODO:
symbolTable.relateToOperator("tex2Dbias", EOpTextureBias);
symbolTable.relateToOperator("tex2Dgrad", EOpTextureGrad);
symbolTable.relateToOperator("tex2Dlod", EOpTextureLod);
// symbolTable.relateToOperator("tex2Dproj", EOpTextureProj);
symbolTable.relateToOperator("tex2Dproj", EOpTextureProj);
symbolTable.relateToOperator("tex3D", EOpTexture);
// symbolTable.relateToOperator("tex3Dbias"); // TODO
symbolTable.relateToOperator("tex3Dbias", EOpTextureBias);
symbolTable.relateToOperator("tex3Dgrad", EOpTextureGrad);
symbolTable.relateToOperator("tex3Dlod", EOpTextureLod);
// symbolTable.relateToOperator("tex3Dproj", EOpTextureProj);
symbolTable.relateToOperator("tex3Dproj", EOpTextureProj);
symbolTable.relateToOperator("texCUBE", EOpTexture);
// symbolTable.relateToOperator("texCUBEbias", // TODO
symbolTable.relateToOperator("texCUBEbias", EOpTextureBias);
symbolTable.relateToOperator("texCUBEgrad", EOpTextureGrad);
symbolTable.relateToOperator("texCUBElod", EOpTextureLod);
// symbolTable.relateToOperator("texCUBEproj", EOpTextureProj);
symbolTable.relateToOperator("texCUBEproj", EOpTextureProj);
symbolTable.relateToOperator("transpose", EOpTranspose);
symbolTable.relateToOperator("trunc", EOpTrunc);
}

View File

@@ -54,6 +54,9 @@ public:
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable);
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
private:
void createMatTimesMat();
};
} // end namespace glslang