Skip to content

Commit 7d2e16b

Browse files
Complete HLSLTranslator matrix support
1 parent 85bb5f9 commit 7d2e16b

File tree

8 files changed

+763
-411
lines changed

8 files changed

+763
-411
lines changed

src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.cpp

Lines changed: 173 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,15 @@ static const char* GetTypeName(const HLSLType& type)
5252
case HLSLBaseType_Float2: return "vec2";
5353
case HLSLBaseType_Float3: return "vec3";
5454
case HLSLBaseType_Float4: return "vec4";
55-
case HLSLBaseType_Float2x2: return "mat2";
55+
case HLSLBaseType_Float2x4: return "mat4x2";
56+
case HLSLBaseType_Float2x3: return "mat3x2";
57+
case HLSLBaseType_Float2x2: return "mat2";
58+
case HLSLBaseType_Float3x4: return "mat4x3";
5659
case HLSLBaseType_Float3x3: return "mat3";
60+
case HLSLBaseType_Float3x2: return "mat2x3";
5761
case HLSLBaseType_Float4x4: return "mat4";
58-
case HLSLBaseType_Float4x3: return "mat4";
59-
case HLSLBaseType_Float4x2: return "mat4";
60-
case HLSLBaseType_Half: return "float";
61-
case HLSLBaseType_Half2: return "vec2";
62-
case HLSLBaseType_Half3: return "vec3";
63-
case HLSLBaseType_Half4: return "vec4";
64-
case HLSLBaseType_Half2x2: return "mat2";
65-
case HLSLBaseType_Half3x3: return "mat3";
66-
case HLSLBaseType_Half4x4: return "mat4";
67-
case HLSLBaseType_Half4x3: return "mat4";
68-
case HLSLBaseType_Half4x2: return "mat4";
62+
case HLSLBaseType_Float4x3: return "mat3x4";
63+
case HLSLBaseType_Float4x2: return "mat2x4";
6964
case HLSLBaseType_Bool: return "bool";
7065
case HLSLBaseType_Bool2: return "bvec2";
7166
case HLSLBaseType_Bool3: return "bvec3";
@@ -399,6 +394,21 @@ bool GLSLGenerator::Generate(HLSLTree* tree, Target target, Version version, con
399394
m_writer.WriteLine( 0, "vec3 %s(bvec3 cond, vec3 trueExpr, vec3 falseExpr) { vec3 ret; ret.x = cond.x ? trueExpr.x : falseExpr.x; ret.y = cond.y ? trueExpr.y : falseExpr.y; ret.z = cond.z ? trueExpr.z : falseExpr.z; return ret; }", m_bvecTernary );
400395
m_writer.WriteLine( 0, "vec4 %s(bvec4 cond, vec4 trueExpr, vec4 falseExpr) { vec4 ret; ret.x = cond.x ? trueExpr.x : falseExpr.x; ret.y = cond.y ? trueExpr.y : falseExpr.y; ret.z = cond.z ? trueExpr.z : falseExpr.z; ret.w = cond.w ? trueExpr.w : falseExpr.w; return ret; }", m_bvecTernary );
401396

397+
m_tree->EnumerateMatrixCtorsNeeded(matrixCtors);
398+
for(matrixCtor & ctor : matrixCtors)
399+
{
400+
std::string id = GetTypeName(HLSLType(ctor.matrixType));
401+
id += "_from";
402+
for(HLSLBaseType argType : ctor.argumentTypes)
403+
{
404+
id += "_";
405+
id += GetTypeName(HLSLType(argType));
406+
}
407+
matrixCtorsId[ctor] = id;
408+
}
409+
410+
OutputMatrixCtors();
411+
402412
// Output the extension used for dFdx/dFdy in GLES2
403413
if (m_version == Version_100_ES && (m_tree->NeedsFunction("ddx") || m_tree->NeedsFunction("ddy")))
404414
{
@@ -464,8 +474,7 @@ const HLSLType* commonScalarType(const HLSLType& lhs, const HLSLType& rhs)
464474
if (!IsScalarType(lhs) || !IsScalarType(rhs))
465475
return NULL;
466476

467-
if (lhs.baseType == HLSLBaseType_Float || lhs.baseType == HLSLBaseType_Half ||
468-
rhs.baseType == HLSLBaseType_Float || rhs.baseType == HLSLBaseType_Half)
477+
if (lhs.baseType == HLSLBaseType_Float || rhs.baseType == HLSLBaseType_Float)
469478
return &kFloatType;
470479

471480
if (lhs.baseType == HLSLBaseType_Uint || rhs.baseType == HLSLBaseType_Uint)
@@ -510,9 +519,31 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
510519
else if (expression->nodeType == HLSLNodeType_ConstructorExpression)
511520
{
512521
HLSLConstructorExpression* constructorExpression = static_cast<HLSLConstructorExpression*>(expression);
513-
m_writer.Write("%s(", GetTypeName(constructorExpression->type));
514-
OutputExpressionList(constructorExpression->argument);
515-
m_writer.Write(")");
522+
523+
bool matrixCtorNeeded = false;
524+
if (IsMatrixType(constructorExpression->type.baseType))
525+
{
526+
matrixCtor ctor = matrixCtorBuilder(constructorExpression->type, constructorExpression->argument);
527+
if (std::find(matrixCtors.cbegin(), matrixCtors.cend(), ctor) != matrixCtors.cend())
528+
{
529+
matrixCtorNeeded = true;
530+
}
531+
}
532+
533+
if (matrixCtorNeeded)
534+
{
535+
// Matrix contructors needs to be adapted since GLSL access a matrix as m[c][r] while HLSL is m[r][c]
536+
matrixCtor ctor = matrixCtorBuilder(constructorExpression->type, constructorExpression->argument);
537+
m_writer.Write("%s(", matrixCtorsId[ctor].c_str());
538+
OutputExpressionList(constructorExpression->argument);
539+
m_writer.Write(")");
540+
}
541+
else
542+
{
543+
m_writer.Write("%s(", GetTypeName(constructorExpression->type));
544+
OutputExpressionList(constructorExpression->argument);
545+
m_writer.Write(")");
546+
}
516547
}
517548
else if (expression->nodeType == HLSLNodeType_CastingExpression)
518549
{
@@ -527,7 +558,6 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
527558
HLSLLiteralExpression* literalExpression = static_cast<HLSLLiteralExpression*>(expression);
528559
switch (literalExpression->type)
529560
{
530-
case HLSLBaseType_Half:
531561
case HLSLBaseType_Float:
532562
{
533563
// Don't use printf directly so that we don't use the system locale.
@@ -676,8 +706,7 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
676706

677707
HLSLMemberAccess* memberAccess = static_cast<HLSLMemberAccess*>(expression);
678708

679-
if (memberAccess->object->expressionType.baseType == HLSLBaseType_Half ||
680-
memberAccess->object->expressionType.baseType == HLSLBaseType_Float ||
709+
if (memberAccess->object->expressionType.baseType == HLSLBaseType_Float ||
681710
memberAccess->object->expressionType.baseType == HLSLBaseType_Int ||
682711
memberAccess->object->expressionType.baseType == HLSLBaseType_Uint)
683712
{
@@ -705,12 +734,7 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
705734
OutputExpression(memberAccess->object);
706735
m_writer.Write(")");
707736

708-
if( memberAccess->object->expressionType.baseType == HLSLBaseType_Float2x2 ||
709-
memberAccess->object->expressionType.baseType == HLSLBaseType_Float3x3 ||
710-
memberAccess->object->expressionType.baseType == HLSLBaseType_Float4x4 ||
711-
memberAccess->object->expressionType.baseType == HLSLBaseType_Half2x2 ||
712-
memberAccess->object->expressionType.baseType == HLSLBaseType_Half3x3 ||
713-
memberAccess->object->expressionType.baseType == HLSLBaseType_Half4x4 )
737+
if( IsMatrixType(memberAccess->object->expressionType.baseType))
714738
{
715739
// Handle HLSL matrix "swizzling".
716740
// TODO: Properly handle multiple element selection such as _m00_m12
@@ -754,12 +778,7 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
754778
HLSLArrayAccess* arrayAccess = static_cast<HLSLArrayAccess*>(expression);
755779

756780
if (!arrayAccess->array->expressionType.array &&
757-
(arrayAccess->array->expressionType.baseType == HLSLBaseType_Float2x2 ||
758-
arrayAccess->array->expressionType.baseType == HLSLBaseType_Float3x3 ||
759-
arrayAccess->array->expressionType.baseType == HLSLBaseType_Float4x4 ||
760-
arrayAccess->array->expressionType.baseType == HLSLBaseType_Half2x2 ||
761-
arrayAccess->array->expressionType.baseType == HLSLBaseType_Half3x3 ||
762-
arrayAccess->array->expressionType.baseType == HLSLBaseType_Half4x4 ) )
781+
IsMatrixType(arrayAccess->array->expressionType.baseType) )
763782
{
764783
// GLSL access a matrix as m[c][r] while HLSL is m[r][c], so use our
765784
// special row access function to convert.
@@ -859,19 +878,10 @@ void GLSLGenerator::OutputExpression(HLSLExpression* expression, const HLSLType*
859878

860879
if (cast)
861880
{
862-
/*
863-
const BaseTypeDescription& srcTypeDesc = _baseTypeDescriptions[expression->expressionType.baseType];
864-
const BaseTypeDescription& dstTypeDesc = _baseTypeDescriptions[dstType->baseType];
865-
866-
if (dstTypeDesc.numDimensions == 1 && dstTypeDesc.numComponents > 1)
881+
if (IsVectorType(dstType->baseType) || IsMatrixType(dstType->baseType))
867882
{
868-
// Casting to a vector - pad with 0s
869-
for (int i = srcTypeDesc.numComponents; i < dstTypeDesc.numComponents; ++i)
870-
{
871-
m_writer.Write(", 0");
872-
}
883+
CompleteConstructorArguments(expression, dstType->baseType);
873884
}
874-
*/
875885

876886
m_writer.Write(")");
877887
}
@@ -1824,8 +1834,31 @@ void GLSLGenerator::OutputDeclaration(HLSLDeclaration* declaration)
18241834
m_writer.Write( " )" );
18251835
}
18261836
else
1827-
{
1828-
OutputExpression( declaration->assignment, &declaration->type );
1837+
{
1838+
bool matrixCtorNeeded = false;
1839+
if (IsMatrixType(declaration->type.baseType))
1840+
{
1841+
matrixCtor ctor = matrixCtorBuilder(declaration->type, declaration->assignment);
1842+
if (std::find(matrixCtors.cbegin(), matrixCtors.cend(), ctor) != matrixCtors.cend())
1843+
{
1844+
matrixCtorNeeded = true;
1845+
}
1846+
}
1847+
1848+
if (matrixCtorNeeded)
1849+
{
1850+
// Matrix contructors needs to be adapted since GLSL access a matrix as m[c][r] while HLSL is m[r][c]
1851+
matrixCtor ctor = matrixCtorBuilder(declaration->type, declaration->assignment);
1852+
m_writer.Write("%s(", matrixCtorsId[ctor].c_str());
1853+
OutputExpressionList(declaration->assignment);
1854+
m_writer.Write(")");
1855+
}
1856+
else
1857+
{
1858+
m_writer.Write( "%s( ", GetTypeName( declaration->type ) );
1859+
OutputExpressionList( declaration->assignment );
1860+
m_writer.Write( " )" );
1861+
}
18291862
}
18301863
}
18311864

@@ -1959,4 +1992,99 @@ const char* GLSLGenerator::GetBuiltInSemantic(const char* semantic, AttributeMod
19591992
return NULL;
19601993
}
19611994

1995+
void GLSLGenerator::CompleteConstructorArguments(HLSLExpression* expression, HLSLBaseType dstType)
1996+
{
1997+
int nbComponentsProvided = 0;
1998+
int nbComponentsNeeded = 0;
1999+
2000+
const BaseTypeDescription& dstTypeDesc = baseTypeDescriptions[dstType];
2001+
nbComponentsNeeded = dstTypeDesc.numComponents * dstTypeDesc.height;
2002+
2003+
const BaseTypeDescription& srcTypeDesc = baseTypeDescriptions[expression->expressionType.baseType];
2004+
nbComponentsProvided = srcTypeDesc.numComponents * srcTypeDesc.height;
2005+
if (IsMatrixType(expression->expressionType.baseType) ||
2006+
IsVectorType(expression->expressionType.baseType) )
2007+
{
2008+
for(int i = nbComponentsProvided; i < nbComponentsNeeded; i++)
2009+
{
2010+
m_writer.Write(", 0");
2011+
}
2012+
}
2013+
}
2014+
2015+
2016+
void GLSLGenerator::OutputMatrixCtors() {
2017+
for(matrixCtor & ctor : matrixCtors)
2018+
{
2019+
m_writer.Write("%s %s(",
2020+
GetTypeName(HLSLType(ctor.matrixType)),
2021+
matrixCtorsId[ctor].c_str());
2022+
int argNum = 0;
2023+
for(HLSLBaseType argType : ctor.argumentTypes)
2024+
{
2025+
if (argNum == 0)
2026+
{
2027+
m_writer.Write("%s %c", GetTypeName(HLSLType(argType)), 'a' + argNum);
2028+
}
2029+
else
2030+
{
2031+
m_writer.Write(", %s %c", GetTypeName(HLSLType(argType)), 'a' + argNum);
2032+
}
2033+
argNum++;
2034+
}
2035+
m_writer.Write( ") { return %s(", GetTypeName(HLSLType(ctor.matrixType)));
2036+
2037+
const BaseTypeDescription& ctorTypeDesc = baseTypeDescriptions[ctor.matrixType];
2038+
std::vector<std::string> args(ctorTypeDesc.numComponents * ctorTypeDesc.height, "0");
2039+
int argNumIn = 0;
2040+
int argNumOut = 0;
2041+
for(HLSLBaseType argType : ctor.argumentTypes)
2042+
{
2043+
std::string arg;
2044+
arg += 'a' + argNumIn;
2045+
2046+
if (IsScalarType(argType))
2047+
{
2048+
int index = (argNumOut % ctorTypeDesc.height) * (ctorTypeDesc.numComponents) +
2049+
(argNumOut / ctorTypeDesc.height);
2050+
args[index] = arg;
2051+
argNumOut++;
2052+
}
2053+
else if (IsVectorType(argType))
2054+
{
2055+
const BaseTypeDescription& argTypeDesc = baseTypeDescriptions[argType];
2056+
for(int dim = 0; dim < argTypeDesc.numComponents; dim++)
2057+
{
2058+
std::string argVect = arg + ".";
2059+
argVect += "xyzw"[dim];
2060+
int index = (argNumOut % ctorTypeDesc.height) * (ctorTypeDesc.numComponents) +
2061+
(argNumOut / ctorTypeDesc.height);
2062+
args[index] = argVect;
2063+
argNumOut++;
2064+
}
2065+
}
2066+
2067+
argNumIn++;
2068+
}
2069+
2070+
bool first = true;
2071+
for(std::string & arg : args)
2072+
{
2073+
if (!first)
2074+
{
2075+
m_writer.Write(",%s", arg.c_str());
2076+
}
2077+
else
2078+
{
2079+
m_writer.Write("%s", arg.c_str());
2080+
}
2081+
first = false;
2082+
}
2083+
2084+
m_writer.Write("); }");
2085+
m_writer.EndLine();
2086+
}
2087+
}
2088+
2089+
19622090
}

src/libprojectM/Renderer/hlslparser/src/GLSLGenerator.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ class GLSLGenerator
116116

117117
const char* GetBuiltInSemantic(const char* semantic, AttributeModifier modifier, int* outputIndex = 0);
118118
const char* GetAttribQualifier(AttributeModifier modifier);
119+
void CompleteConstructorArguments(HLSLExpression* expression, HLSLBaseType dstType);
120+
void OutputMatrixCtors();
119121

120122
private:
121123

@@ -157,6 +159,9 @@ class GLSLGenerator
157159

158160
char m_reservedWord[s_numReservedWords][64];
159161

162+
std::vector<matrixCtor> matrixCtors;
163+
std::map<matrixCtor,std::string> matrixCtorsId;
164+
160165
};
161166

162167
}

0 commit comments

Comments
 (0)