Add support for non-square matrices to the shader translator.

TRAC #23081 Signed-off-by: Geoff Lang Signed-off-by: Nicolas Capens Author: Jamie Madill git-svn-id: https://angleproject.googlecode.com/svn/branches/es3proto@2394 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 4f35fdf6
...@@ -240,6 +240,33 @@ bool IsMatrixType(GLenum type) ...@@ -240,6 +240,33 @@ bool IsMatrixType(GLenum type)
return VariableRowCount(type) > 1; return VariableRowCount(type) > 1;
} }
GLenum TransposeMatrixType(GLenum type)
{
if (!IsMatrixType(type))
{
return type;
}
switch (type)
{
case GL_FLOAT_MAT2: return GL_FLOAT_MAT2;
case GL_FLOAT_MAT3: return GL_FLOAT_MAT3;
case GL_FLOAT_MAT4: return GL_FLOAT_MAT4;
case GL_FLOAT_MAT2x3: return GL_FLOAT_MAT3x2;
case GL_FLOAT_MAT3x2: return GL_FLOAT_MAT2x3;
case GL_FLOAT_MAT2x4: return GL_FLOAT_MAT4x2;
case GL_FLOAT_MAT4x2: return GL_FLOAT_MAT2x4;
case GL_FLOAT_MAT3x4: return GL_FLOAT_MAT4x3;
case GL_FLOAT_MAT4x3: return GL_FLOAT_MAT3x4;
default: UNREACHABLE(); return GL_NONE;
}
}
int AttributeRegisterCount(GLenum type)
{
return IsMatrixType(type) ? VariableColumnCount(type) : 1;
}
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize) int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize)
{ {
ASSERT(allocationSize <= bitsSize); ASSERT(allocationSize <= bitsSize);
......
...@@ -33,6 +33,8 @@ GLenum UniformBoolVectorType(GLenum type); ...@@ -33,6 +33,8 @@ GLenum UniformBoolVectorType(GLenum type);
int VariableRowCount(GLenum type); int VariableRowCount(GLenum type);
int VariableColumnCount(GLenum type); int VariableColumnCount(GLenum type);
bool IsMatrixType(GLenum type); bool IsMatrixType(GLenum type);
GLenum TransposeMatrixType(GLenum type);
int AttributeRegisterCount(GLenum type);
int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize); int AllocateFirstFreeBits(unsigned int *bits, unsigned int allocationSize, unsigned int bitsSize);
......
#define MAJOR_VERSION 1 #define MAJOR_VERSION 1
#define MINOR_VERSION 1 #define MINOR_VERSION 1
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 1992 #define BUILD_REVISION 1993
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -972,6 +972,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -972,6 +972,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
if (left->isVector()) if (left->isVector())
{ {
op = EOpVectorTimesMatrix; op = EOpVectorTimesMatrix;
setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), 1));
} }
else else
{ {
...@@ -994,6 +995,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -994,6 +995,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
else if (left->isMatrix() && right->isMatrix()) else if (left->isMatrix() && right->isMatrix())
{ {
op = EOpMatrixTimesMatrix; op = EOpMatrixTimesMatrix;
setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows()));
} }
else if (!left->isMatrix() && !right->isMatrix()) else if (!left->isMatrix() && !right->isMatrix())
{ {
...@@ -1045,6 +1047,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink) ...@@ -1045,6 +1047,7 @@ bool TIntermBinary::promote(TInfoSink& infoSink)
else if (left->isMatrix() && right->isMatrix()) else if (left->isMatrix() && right->isMatrix())
{ {
op = EOpMatrixTimesMatrixAssign; op = EOpMatrixTimesMatrixAssign;
setType(TType(basicType, higherPrecision, EvqTemporary, right->getCols(), left->getRows()));
} }
else if (!left->isMatrix() && !right->isMatrix()) else if (!left->isMatrix() && !right->isMatrix())
{ {
......
...@@ -68,9 +68,14 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc ...@@ -68,9 +68,14 @@ OutputHLSL::OutputHLSL(TParseContext &context, const ShBuiltInResources& resourc
mUsesFaceforward2 = false; mUsesFaceforward2 = false;
mUsesFaceforward3 = false; mUsesFaceforward3 = false;
mUsesFaceforward4 = false; mUsesFaceforward4 = false;
mUsesEqualMat2 = false;
mUsesEqualMat3 = false; for (unsigned int col = 0; col <= 4; col++)
mUsesEqualMat4 = false; {
for (unsigned int row = 0; row <= 4; row++)
{
mUsesEqualMat[col][row] = false;
}
}
mUsesEqualVec2 = false; mUsesEqualVec2 = false;
mUsesEqualVec3 = false; mUsesEqualVec3 = false;
mUsesEqualVec4 = false; mUsesEqualVec4 = false;
...@@ -150,7 +155,7 @@ const ActiveInterfaceBlocks &OutputHLSL::getInterfaceBlocks() const ...@@ -150,7 +155,7 @@ const ActiveInterfaceBlocks &OutputHLSL::getInterfaceBlocks() const
int OutputHLSL::vectorSize(const TType &type) const int OutputHLSL::vectorSize(const TType &type) const
{ {
int elementSize = type.isMatrix() ? type.getRows() : 1; int elementSize = type.isMatrix() ? type.getCols() : 1;
int arraySize = type.isArray() ? type.getArraySize() : 1; int arraySize = type.isArray() ? type.getArraySize() : 1;
return elementSize * arraySize; return elementSize * arraySize;
...@@ -1168,34 +1173,51 @@ void OutputHLSL::header() ...@@ -1168,34 +1173,51 @@ void OutputHLSL::header()
"\n"; "\n";
} }
if (mUsesEqualMat2) for (unsigned int cols = 2; cols <= 4; cols++)
{ {
out << "bool equal(float2x2 m, float2x2 n)\n" for (unsigned int rows = 2; rows <= 4; rows++)
"{\n" {
" return m[0][0] == n[0][0] && m[0][1] == n[0][1] &&\n" if (mUsesEqualMat[cols][rows])
" m[1][0] == n[1][0] && m[1][1] == n[1][1];\n" {
"}\n"; TString matrixType = "float" + str(cols) + "x" + str(rows);
}
if (mUsesEqualMat3) out << "bool equal(" + matrixType + " m, " + matrixType + " n)\n"
{ "{\n";
out << "bool equal(float3x3 m, float3x3 n)\n"
"{\n"
" return m[0][0] == n[0][0] && m[0][1] == n[0][1] && m[0][2] == n[0][2] &&\n"
" m[1][0] == n[1][0] && m[1][1] == n[1][1] && m[1][2] == n[1][2] &&\n"
" m[2][0] == n[2][0] && m[2][1] == n[2][1] && m[2][2] == n[2][2];\n"
"}\n";
}
if (mUsesEqualMat4) for (unsigned int row = 0; row < rows; row++)
{ {
out << "bool equal(float4x4 m, float4x4 n)\n" if (row == 0)
"{\n" {
" return m[0][0] == n[0][0] && m[0][1] == n[0][1] && m[0][2] == n[0][2] && m[0][3] == n[0][3] &&\n" out << " return ";
" m[1][0] == n[1][0] && m[1][1] == n[1][1] && m[1][2] == n[1][2] && m[1][3] == n[1][3] &&\n" }
" m[2][0] == n[2][0] && m[2][1] == n[2][1] && m[2][2] == n[2][2] && m[2][3] == n[2][3] &&\n" else
" m[3][0] == n[3][0] && m[3][1] == n[3][1] && m[3][2] == n[3][2] && m[3][3] == n[3][3];\n" {
"}\n"; out << " ";
}
for (unsigned int col = 0; col < cols; col++)
{
TString index = "[" + str(col) + "][" + str(row) + "]";
out << "m" + index + " == n" + index;
if (col == cols-1 && row == rows-1)
{
out << ";\n";
}
else if (col == cols-1)
{
out << " &&\n";
}
else
{
out << " && ";
}
}
}
out << "}\n";
}
}
} }
if (mUsesEqualVec2) if (mUsesEqualVec2)
...@@ -1573,13 +1595,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node) ...@@ -1573,13 +1595,7 @@ bool OutputHLSL::visitBinary(Visit visit, TIntermBinary *node)
{ {
if (node->getLeft()->isMatrix()) if (node->getLeft()->isMatrix())
{ {
switch (node->getLeft()->getRows()) mUsesEqualMat[node->getLeft()->getCols()][node->getLeft()->getRows()] = true;
{
case 2: mUsesEqualMat2 = true; break;
case 3: mUsesEqualMat3 = true; break;
case 4: mUsesEqualMat4 = true; break;
default: UNREACHABLE();
}
} }
else if (node->getLeft()->isVector()) else if (node->getLeft()->isVector())
{ {
...@@ -2816,12 +2832,9 @@ TString OutputHLSL::typeString(const TType &type) ...@@ -2816,12 +2832,9 @@ TString OutputHLSL::typeString(const TType &type)
} }
else if (type.isMatrix()) else if (type.isMatrix())
{ {
switch (type.getRows()) int cols = type.getCols();
{ int rows = type.getRows();
case 2: return "float2x2"; return "float" + str(cols) + "x" + str(rows);
case 3: return "float3x3";
case 4: return "float4x4";
}
} }
else else
{ {
...@@ -3352,11 +3365,35 @@ GLenum OutputHLSL::glVariableType(const TType &type) ...@@ -3352,11 +3365,35 @@ GLenum OutputHLSL::glVariableType(const TType &type)
} }
else if (type.isMatrix()) else if (type.isMatrix())
{ {
switch(type.getRows()) switch (type.getCols())
{ {
case 2: return GL_FLOAT_MAT2; case 2:
case 3: return GL_FLOAT_MAT3; switch(type.getRows())
case 4: return GL_FLOAT_MAT4; {
case 2: return GL_FLOAT_MAT2;
case 3: return GL_FLOAT_MAT2x3;
case 4: return GL_FLOAT_MAT2x4;
default: UNREACHABLE();
}
case 3:
switch(type.getRows())
{
case 2: return GL_FLOAT_MAT3x2;
case 3: return GL_FLOAT_MAT3;
case 4: return GL_FLOAT_MAT3x4;
default: UNREACHABLE();
}
case 4:
switch(type.getRows())
{
case 2: return GL_FLOAT_MAT4x2;
case 3: return GL_FLOAT_MAT4x3;
case 4: return GL_FLOAT_MAT4;
default: UNREACHABLE();
}
default: UNREACHABLE(); default: UNREACHABLE();
} }
} }
......
...@@ -124,9 +124,7 @@ class OutputHLSL : public TIntermTraverser ...@@ -124,9 +124,7 @@ class OutputHLSL : public TIntermTraverser
bool mUsesFaceforward2; bool mUsesFaceforward2;
bool mUsesFaceforward3; bool mUsesFaceforward3;
bool mUsesFaceforward4; bool mUsesFaceforward4;
bool mUsesEqualMat2; bool mUsesEqualMat[5][5];
bool mUsesEqualMat3;
bool mUsesEqualMat4;
bool mUsesEqualVec2; bool mUsesEqualVec2;
bool mUsesEqualVec3; bool mUsesEqualVec3;
bool mUsesEqualVec4; bool mUsesEqualVec4;
......
...@@ -1355,7 +1355,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T ...@@ -1355,7 +1355,7 @@ TIntermTyped* TParseContext::addConstMatrixNode(int index, TIntermTyped* node, T
TIntermTyped* typedNode; TIntermTyped* typedNode;
TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion(); TIntermConstantUnion* tempConstantNode = node->getAsConstantUnion();
if (index >= node->getType().getRows()) { if (index >= node->getType().getCols()) {
std::stringstream extraInfoStream; std::stringstream extraInfoStream;
extraInfoStream << "matrix field selection out of range '" << index << "'"; extraInfoStream << "matrix field selection out of range '" << index << "'";
std::string extraInfo = extraInfoStream.str(); std::string extraInfo = extraInfoStream.str();
......
...@@ -131,6 +131,17 @@ O [0-7] ...@@ -131,6 +131,17 @@ O [0-7]
"mat3" { context->lexAfterType = true; return(MATRIX3); } "mat3" { context->lexAfterType = true; return(MATRIX3); }
"mat4" { context->lexAfterType = true; return(MATRIX4); } "mat4" { context->lexAfterType = true; return(MATRIX4); }
"mat2x2" { return ES2_ident_ES3_keyword(context, MATRIX2); }
"mat3x3" { return ES2_ident_ES3_keyword(context, MATRIX3); }
"mat4x4" { return ES2_ident_ES3_keyword(context, MATRIX4); }
"mat2x3" { return ES2_ident_ES3_keyword(context, MATRIX2x3); }
"mat3x2" { return ES2_ident_ES3_keyword(context, MATRIX3x2); }
"mat2x4" { return ES2_ident_ES3_keyword(context, MATRIX2x4); }
"mat4x2" { return ES2_ident_ES3_keyword(context, MATRIX4x2); }
"mat3x4" { return ES2_ident_ES3_keyword(context, MATRIX3x4); }
"mat4x3" { return ES2_ident_ES3_keyword(context, MATRIX4x3); }
"vec2" { context->lexAfterType = true; return (VEC2); } "vec2" { context->lexAfterType = true; return (VEC2); }
"vec3" { context->lexAfterType = true; return (VEC3); } "vec3" { context->lexAfterType = true; return (VEC3); }
"vec4" { context->lexAfterType = true; return (VEC4); } "vec4" { context->lexAfterType = true; return (VEC4); }
......
...@@ -126,6 +126,7 @@ extern void yyerror(TParseContext* context, const char* reason); ...@@ -126,6 +126,7 @@ extern void yyerror(TParseContext* context, const char* reason);
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT %token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4 %token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING %token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
%token <lex> MATRIX2x3 MATRIX3x2 MATRIX2x4 MATRIX4x2 MATRIX3x4 MATRIX4x3
%token <lex> CENTROID FLAT SMOOTH %token <lex> CENTROID FLAT SMOOTH
%token <lex> STRUCT VOID_TYPE WHILE %token <lex> STRUCT VOID_TYPE WHILE
%token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT %token <lex> SAMPLER2D SAMPLERCUBE SAMPLER_EXTERNAL_OES SAMPLER2DRECT
...@@ -1606,6 +1607,36 @@ type_specifier_nonarray ...@@ -1606,6 +1607,36 @@ type_specifier_nonarray
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(4, 4); $$.setMatrix(4, 4);
} }
| MATRIX2x3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(2, 3);
}
| MATRIX3x2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(3, 2);
}
| MATRIX2x4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(2, 4);
}
| MATRIX4x2 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(4, 2);
}
| MATRIX3x4 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(3, 4);
}
| MATRIX4x3 {
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setMatrix(4, 3);
}
| SAMPLER2D { | SAMPLER2D {
FRAG_VERT_ONLY("sampler2D", $1.line); FRAG_VERT_ONLY("sampler2D", $1.line);
TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = context->symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
......
...@@ -84,70 +84,76 @@ extern int yydebug; ...@@ -84,70 +84,76 @@ extern int yydebug;
INOUT_QUAL = 293, INOUT_QUAL = 293,
UNIFORM = 294, UNIFORM = 294,
VARYING = 295, VARYING = 295,
CENTROID = 296, MATRIX2x3 = 296,
FLAT = 297, MATRIX3x2 = 297,
SMOOTH = 298, MATRIX2x4 = 298,
STRUCT = 299, MATRIX4x2 = 299,
VOID_TYPE = 300, MATRIX3x4 = 300,
WHILE = 301, MATRIX4x3 = 301,
SAMPLER2D = 302, CENTROID = 302,
SAMPLERCUBE = 303, FLAT = 303,
SAMPLER_EXTERNAL_OES = 304, SMOOTH = 304,
SAMPLER2DRECT = 305, STRUCT = 305,
SAMPLER3D = 306, VOID_TYPE = 306,
SAMPLER3DRECT = 307, WHILE = 307,
SAMPLER2DSHADOW = 308, SAMPLER2D = 308,
IDENTIFIER = 309, SAMPLERCUBE = 309,
TYPE_NAME = 310, SAMPLER_EXTERNAL_OES = 310,
FLOATCONSTANT = 311, SAMPLER2DRECT = 311,
INTCONSTANT = 312, SAMPLER3D = 312,
BOOLCONSTANT = 313, SAMPLER3DRECT = 313,
FIELD_SELECTION = 314, SAMPLER2DSHADOW = 314,
LEFT_OP = 315, IDENTIFIER = 315,
RIGHT_OP = 316, TYPE_NAME = 316,
INC_OP = 317, FLOATCONSTANT = 317,
DEC_OP = 318, INTCONSTANT = 318,
LE_OP = 319, BOOLCONSTANT = 319,
GE_OP = 320, FIELD_SELECTION = 320,
EQ_OP = 321, LEFT_OP = 321,
NE_OP = 322, RIGHT_OP = 322,
AND_OP = 323, INC_OP = 323,
OR_OP = 324, DEC_OP = 324,
XOR_OP = 325, LE_OP = 325,
MUL_ASSIGN = 326, GE_OP = 326,
DIV_ASSIGN = 327, EQ_OP = 327,
ADD_ASSIGN = 328, NE_OP = 328,
MOD_ASSIGN = 329, AND_OP = 329,
LEFT_ASSIGN = 330, OR_OP = 330,
RIGHT_ASSIGN = 331, XOR_OP = 331,
AND_ASSIGN = 332, MUL_ASSIGN = 332,
XOR_ASSIGN = 333, DIV_ASSIGN = 333,
OR_ASSIGN = 334, ADD_ASSIGN = 334,
SUB_ASSIGN = 335, MOD_ASSIGN = 335,
LEFT_PAREN = 336, LEFT_ASSIGN = 336,
RIGHT_PAREN = 337, RIGHT_ASSIGN = 337,
LEFT_BRACKET = 338, AND_ASSIGN = 338,
RIGHT_BRACKET = 339, XOR_ASSIGN = 339,
LEFT_BRACE = 340, OR_ASSIGN = 340,
RIGHT_BRACE = 341, SUB_ASSIGN = 341,
DOT = 342, LEFT_PAREN = 342,
COMMA = 343, RIGHT_PAREN = 343,
COLON = 344, LEFT_BRACKET = 344,
EQUAL = 345, RIGHT_BRACKET = 345,
SEMICOLON = 346, LEFT_BRACE = 346,
BANG = 347, RIGHT_BRACE = 347,
DASH = 348, DOT = 348,
TILDE = 349, COMMA = 349,
PLUS = 350, COLON = 350,
STAR = 351, EQUAL = 351,
SLASH = 352, SEMICOLON = 352,
PERCENT = 353, BANG = 353,
LEFT_ANGLE = 354, DASH = 354,
RIGHT_ANGLE = 355, TILDE = 355,
VERTICAL_BAR = 356, PLUS = 356,
CARET = 357, STAR = 357,
AMPERSAND = 358, SLASH = 358,
QUESTION = 359 PERCENT = 359,
LEFT_ANGLE = 360,
RIGHT_ANGLE = 361,
VERTICAL_BAR = 362,
CARET = 363,
AMPERSAND = 364,
QUESTION = 365
}; };
#endif #endif
......
...@@ -22,8 +22,9 @@ public: ...@@ -22,8 +22,9 @@ public:
infoSink(sink), infoSink(sink),
symbolTable(symTable), symbolTable(symTable),
size(0), size(0),
isMatrix(false), isDiagonalMatrixInit(false),
matrixSize(0) { matrixCols(0),
matrixRows(0) {
} }
bool error; bool error;
...@@ -46,8 +47,9 @@ protected: ...@@ -46,8 +47,9 @@ protected:
TInfoSink& infoSink; TInfoSink& infoSink;
TSymbolTable& symbolTable; TSymbolTable& symbolTable;
int size; // size of the constructor ( 4 for vec4) int size; // size of the constructor ( 4 for vec4)
bool isMatrix; bool isDiagonalMatrixInit;
int matrixSize; // dimension of the matrix (nominal size and not the instance size) int matrixCols; // columns of the matrix
int matrixRows; // rows of the matrix
}; };
// //
...@@ -118,8 +120,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -118,8 +120,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
size = node->getType().getObjectSize(); size = node->getType().getObjectSize();
if (node->getType().isMatrix()) { if (node->getType().isMatrix()) {
isMatrix = true; isDiagonalMatrixInit = true;
matrixSize = node->getType().getRows(); matrixCols = node->getType().getCols();
matrixRows = node->getType().getRows();
} }
} }
...@@ -136,8 +139,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node) ...@@ -136,8 +139,9 @@ bool TConstTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
singleConstantParam = false; singleConstantParam = false;
constructorType = EOpNull; constructorType = EOpNull;
size = 0; size = 0;
isMatrix = false; isDiagonalMatrixInit = false;
matrixSize = 0; matrixCols = 0;
matrixRows = 0;
} }
return false; return false;
} }
...@@ -178,7 +182,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) ...@@ -178,7 +182,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
} else { } else {
int totalSize = index + size; int totalSize = index + size;
ConstantUnion *rightUnionArray = node->getUnionArrayPointer(); ConstantUnion *rightUnionArray = node->getUnionArrayPointer();
if (!isMatrix) { if (!isDiagonalMatrixInit) {
int count = 0; int count = 0;
for (int i = index; i < totalSize; i++) { for (int i = index; i < totalSize; i++) {
if (i >= instanceSize) if (i >= instanceSize)
...@@ -191,21 +195,25 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) ...@@ -191,21 +195,25 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
if (node->getType().getObjectSize() > 1) if (node->getType().getObjectSize() > 1)
count++; count++;
} }
} else { // for matrix constructors }
int count = 0; else
int element = index; {
for (int i = index; i < totalSize; i++) { // for matrix diagonal constructors from a single scalar
if (i >= instanceSize) for (int i = 0, col = 0; col < matrixCols; col++)
return; {
if (element - i == 0 || (i - element) % (matrixSize + 1) == 0 ) for (int row = 0; row < matrixRows; row++, i++)
leftUnionArray[i] = rightUnionArray[count]; {
else if (col == row)
leftUnionArray[i].setFConst(0.0f); {
leftUnionArray[i] = rightUnionArray[0];
(index)++; }
else
if (node->getType().getObjectSize() > 1) {
count++; leftUnionArray[i].setFConst(0.0f);
}
(index)++;
}
} }
} }
} }
......
...@@ -876,8 +876,9 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], F ...@@ -876,8 +876,9 @@ int ProgramBinary::packVaryings(InfoLog &infoLog, const Varying *packing[][4], F
for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++) for (VaryingList::iterator varying = fragmentShader->mVaryings.begin(); varying != fragmentShader->mVaryings.end(); varying++)
{ {
int n = VariableRowCount(varying->type) * varying->size; GLenum transposedType = TransposeMatrixType(varying->type);
int m = VariableColumnCount(varying->type); int n = VariableRowCount(transposedType) * varying->size;
int m = VariableColumnCount(transposedType);
bool success = false; bool success = false;
if (m == 2 || m == 3 || m == 4) if (m == 2 || m == 3 || m == 4)
...@@ -1124,7 +1125,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1124,7 +1125,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
int semanticIndex = 0; int semanticIndex = 0;
for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++) for (AttributeArray::iterator attribute = vertexShader->mAttributes.begin(); attribute != vertexShader->mAttributes.end(); attribute++)
{ {
switch (attribute->type) switch (TransposeMatrixType(attribute->type))
{ {
case GL_FLOAT: vertexHLSL += " float "; break; case GL_FLOAT: vertexHLSL += " float "; break;
case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break; case GL_FLOAT_VEC2: vertexHLSL += " float2 "; break;
...@@ -1133,12 +1134,18 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1133,12 +1134,18 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break; case GL_FLOAT_MAT2: vertexHLSL += " float2x2 "; break;
case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break; case GL_FLOAT_MAT3: vertexHLSL += " float3x3 "; break;
case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break; case GL_FLOAT_MAT4: vertexHLSL += " float4x4 "; break;
case GL_FLOAT_MAT2x3: vertexHLSL += " float2x3 "; break;
case GL_FLOAT_MAT3x2: vertexHLSL += " float3x2 "; break;
case GL_FLOAT_MAT2x4: vertexHLSL += " float2x4 "; break;
case GL_FLOAT_MAT4x2: vertexHLSL += " float4x2 "; break;
case GL_FLOAT_MAT3x4: vertexHLSL += " float3x4 "; break;
case GL_FLOAT_MAT4x3: vertexHLSL += " float4x3 "; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n"; vertexHLSL += decorateAttribute(attribute->name) + " : TEXCOORD" + str(semanticIndex) + ";\n";
semanticIndex += VariableRowCount(attribute->type); semanticIndex += AttributeRegisterCount(attribute->type);
} }
vertexHLSL += "};\n" vertexHLSL += "};\n"
...@@ -1177,7 +1184,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1177,7 +1184,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
{ {
vertexHLSL += " " + decorateAttribute(attribute->name) + " = "; vertexHLSL += " " + decorateAttribute(attribute->name) + " = ";
if (VariableRowCount(attribute->type) > 1) // Matrix if (IsMatrixType(attribute->type)) // Matrix
{ {
vertexHLSL += "transpose"; vertexHLSL += "transpose";
} }
...@@ -1230,7 +1237,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1230,7 +1237,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
{ {
for (int i = 0; i < varying->size; i++) for (int i = 0; i < varying->size; i++)
{ {
int rows = VariableRowCount(varying->type); int rows = VariableRowCount(TransposeMatrixType(varying->type));
for (int j = 0; j < rows; j++) for (int j = 0; j < rows; j++)
{ {
...@@ -1404,7 +1411,8 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1404,7 +1411,8 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
{ {
for (int i = 0; i < varying->size; i++) for (int i = 0; i < varying->size; i++)
{ {
int rows = VariableRowCount(varying->type); GLenum transposedType = TransposeMatrixType(varying->type);
int rows = VariableRowCount(transposedType);
for (int j = 0; j < rows; j++) for (int j = 0; j < rows; j++)
{ {
std::string n = str(varying->reg + i * rows + j); std::string n = str(varying->reg + i * rows + j);
...@@ -1420,7 +1428,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying ...@@ -1420,7 +1428,7 @@ bool ProgramBinary::linkVaryings(InfoLog &infoLog, int registers, const Varying
pixelHLSL += "[" + str(j) + "]"; pixelHLSL += "[" + str(j) + "]";
} }
switch (VariableColumnCount(varying->type)) switch (VariableColumnCount(transposedType))
{ {
case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break; case 1: pixelHLSL += " = input.v" + n + ".x;\n"; break;
case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break; case 2: pixelHLSL += " = input.v" + n + ".xy;\n"; break;
...@@ -1469,7 +1477,8 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c ...@@ -1469,7 +1477,8 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c
{ {
for (int i = 0; i < varying->size; i++) for (int i = 0; i < varying->size; i++)
{ {
int rows = VariableRowCount(varying->type); GLenum transposedType = TransposeMatrixType(varying->type);
int rows = VariableRowCount(transposedType);
for (int j = 0; j < rows; j++) for (int j = 0; j < rows; j++)
{ {
switch (varying->interpolation) switch (varying->interpolation)
...@@ -1481,7 +1490,7 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c ...@@ -1481,7 +1490,7 @@ std::string ProgramBinary::generateVaryingHLSL(FragmentShader *fragmentShader, c
} }
std::string n = str(varying->reg + i * rows + j); std::string n = str(varying->reg + i * rows + j);
varyingHLSL += "float" + str(VariableColumnCount(varying->type)) + " v" + n + " : " + varyingSemantic + n + ";\n"; varyingHLSL += "float" + str(VariableColumnCount(transposedType)) + " v" + n + " : " + varyingSemantic + n + ";\n";
} }
} }
} }
...@@ -1988,7 +1997,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at ...@@ -1988,7 +1997,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
if (location == -1) // Not set by glBindAttribLocation if (location == -1) // Not set by glBindAttribLocation
{ {
int rows = VariableRowCount(attribute->type); int rows = AttributeRegisterCount(attribute->type);
int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS); int availableIndex = AllocateFirstFreeBits(&usedLocations, rows, MAX_VERTEX_ATTRIBS);
if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) if (availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS)
...@@ -2005,7 +2014,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at ...@@ -2005,7 +2014,7 @@ bool ProgramBinary::linkAttributes(InfoLog &infoLog, const AttributeBindings &at
for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; ) for (int attributeIndex = 0; attributeIndex < MAX_VERTEX_ATTRIBS; )
{ {
int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name); int index = vertexShader->getSemanticIndex(mLinkedAttribute[attributeIndex].name);
int rows = std::max(VariableRowCount(mLinkedAttribute[attributeIndex].type), 1); int rows = std::max(AttributeRegisterCount(mLinkedAttribute[attributeIndex].type), 1);
for (int r = 0; r < rows; r++) for (int r = 0; r < rows; r++)
{ {
......
...@@ -493,6 +493,30 @@ GLenum Shader::parseType(const std::string &type) ...@@ -493,6 +493,30 @@ GLenum Shader::parseType(const std::string &type)
{ {
return GL_FLOAT_MAT4; return GL_FLOAT_MAT4;
} }
else if (type == "float2x3")
{
return GL_FLOAT_MAT2x3;
}
else if (type == "float3x2")
{
return GL_FLOAT_MAT3x2;
}
else if (type == "float2x4")
{
return GL_FLOAT_MAT2x4;
}
else if (type == "float4x2")
{
return GL_FLOAT_MAT4x2;
}
else if (type == "float3x4")
{
return GL_FLOAT_MAT3x4;
}
else if (type == "float4x3")
{
return GL_FLOAT_MAT4x3;
}
else UNREACHABLE(); else UNREACHABLE();
return GL_NONE; return GL_NONE;
...@@ -504,9 +528,15 @@ static VaryingPriorityMap varyingPriorities; ...@@ -504,9 +528,15 @@ static VaryingPriorityMap varyingPriorities;
static void makeVaryingPriorityMap() static void makeVaryingPriorityMap()
{ {
varyingPriorities[GL_FLOAT_MAT4] = 0; varyingPriorities[GL_FLOAT_MAT4] = 0;
varyingPriorities[GL_FLOAT_MAT3x4] = 10;
varyingPriorities[GL_FLOAT_MAT4x3] = 20;
varyingPriorities[GL_FLOAT_MAT2x4] = 30;
varyingPriorities[GL_FLOAT_MAT4x2] = 40;
varyingPriorities[GL_FLOAT_MAT2] = 50; varyingPriorities[GL_FLOAT_MAT2] = 50;
varyingPriorities[GL_FLOAT_VEC4] = 60; varyingPriorities[GL_FLOAT_VEC4] = 60;
varyingPriorities[GL_FLOAT_MAT3] = 70; varyingPriorities[GL_FLOAT_MAT3] = 70;
varyingPriorities[GL_FLOAT_MAT2x3] = 80;
varyingPriorities[GL_FLOAT_MAT3x2] = 90;
varyingPriorities[GL_FLOAT_VEC3] = 100; varyingPriorities[GL_FLOAT_VEC3] = 100;
varyingPriorities[GL_FLOAT_VEC2] = 110; varyingPriorities[GL_FLOAT_VEC2] = 110;
varyingPriorities[GL_FLOAT] = 120; varyingPriorities[GL_FLOAT] = 120;
...@@ -582,7 +612,7 @@ int VertexShader::getSemanticIndex(const std::string &attributeName) ...@@ -582,7 +612,7 @@ int VertexShader::getSemanticIndex(const std::string &attributeName)
return semanticIndex; return semanticIndex;
} }
semanticIndex += VariableRowCount(attribute->type); semanticIndex += AttributeRegisterCount(attribute->type);
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment