Added support for swizzled matrix assignments and a new "combined" shader test type, with compiles the same source for both vs/fs, but with differing entry points.

Also added a new ETranslateOpTransposeMatrixSwizzles options, which controls how hlsl matrix.m_<row><col> syntax maps to glsl matrix[<row>][<col>]
This commit is contained in:
Jim Sagevid 2012-03-01 12:18:07 +01:00
Родитель ceae3709d2
Коммит 3249bb36b4
12 изменённых файлов: 302 добавлений и 40 удалений

Просмотреть файл

@ -239,11 +239,13 @@ void TGlslOutputTraverser::outputLineDirective (int line)
TGlslOutputTraverser::TGlslOutputTraverser(TInfoSink& i, std::vector<GlslFunction*> &funcList, std::vector<GlslStruct*> &sList, bool usePrecision)
TGlslOutputTraverser::TGlslOutputTraverser(TInfoSink& i, std::vector<GlslFunction*> &funcList, std::vector<GlslStruct*> &sList, bool usePrecision, bool transposeMatrixSwizzles)
: infoSink(i)
, generatingCode(true)
, functionList(funcList)
, structList(sList)
, transposeMatrixSwizzles(transposeMatrixSwizzles)
, swizzleAssignTempCounter(0)
, m_UsePrecision(usePrecision)
, m_LastLineOutput(-1)
{
@ -636,9 +638,14 @@ bool TGlslOutputTraverser::traverseBinary( bool preVisit, TIntermBinary *node, T
for (int ii = 0; ii < (int)goit->indexList.size(); ii++)
{
int val = goit->indexList[ii];
if (goit->transposeMatrixSwizzles) {
collumn[ii] = val%4;
row[ii] = val/4;
} else {
collumn[ii] = val/4;
row[ii] = val%4;
}
}
bool sameCollumn = true;
for (int ii = 1; ii < (int)goit->indexList.size(); ii++)
{
@ -736,6 +743,50 @@ bool TGlslOutputTraverser::traverseBinary( bool preVisit, TIntermBinary *node, T
if (infix)
{
// special case for swizzled matrix assignment
if (node->getLeft() && node->getRight()) {
TIntermBinary* lval = node->getLeft()->getAsBinaryNode();
if (lval && lval->getOp() == EOpMatrixSwizzle) {
static const char* vec_swizzles = "xyzw";
TIntermTyped* rval = node->getRight();
TIntermTyped* lexp = lval->getLeft();
goit->visitConstantUnion = TGlslOutputTraverser::traverseImmediateConstant;
goit->generatingCode = false;
lval->getRight()->traverse(goit);
goit->visitConstantUnion = TGlslOutputTraverser::traverseConstantUnion;
goit->generatingCode = true;
std::vector<int> swizzles = goit->indexList;
goit->indexList.clear();
char temp_rval[128];
snprintf(temp_rval, 128, "xlat_swiztemp%d", goit->swizzleAssignTempCounter++);
unsigned n_swizzles = swizzles.size();
current->beginStatement();
out << "vec" << n_swizzles << " " << temp_rval << " = ";
rval->traverse(goit);
current->endStatement();
for (unsigned i = 0; i != n_swizzles; ++i) {
unsigned a = swizzles[i] / 4, b = swizzles[i] % 4;
unsigned col = goit->transposeMatrixSwizzles ? a : b;
unsigned row = goit->transposeMatrixSwizzles ? b : a;
current->beginStatement();
lexp->traverse(goit);
out << "[" << row << "][" << col << "] = " << temp_rval << "." << vec_swizzles[i];
current->endStatement();
}
return false;
}
}
if (needsParens)
out << '(';

Просмотреть файл

@ -32,7 +32,7 @@ private:
void outputLineDirective (int line);
public:
TGlslOutputTraverser (TInfoSink& i, std::vector<GlslFunction*> &funcList, std::vector<GlslStruct*> &sList, bool usePrecision);
TGlslOutputTraverser (TInfoSink& i, std::vector<GlslFunction*> &funcList, std::vector<GlslStruct*> &sList, bool usePrecision, bool transposeMatrixSwizzles);
GlslStruct *createStructFromType( TType *type );
bool parseInitializer( TIntermBinary *node );
@ -60,6 +60,8 @@ public:
// Persistent data for collecting indices
std::vector<int> indexList;
bool transposeMatrixSwizzles;
unsigned swizzleAssignTempCounter;
bool m_UsePrecision;
int m_LastLineOutput;
};

Просмотреть файл

@ -40,9 +40,9 @@ void HlslCrossCompiler::TransformAST (TIntermNode *root)
PropagateMutableUniforms (root, infoSink);
}
void HlslCrossCompiler::ProduceGLSL (TIntermNode *root, bool usePrecision)
void HlslCrossCompiler::ProduceGLSL (TIntermNode *root, bool usePrecision, bool transposeMatSwizzles)
{
m_GlslProduced = true;
TGlslOutputTraverser glslTraverse (infoSink, functionList, structList, usePrecision);
TGlslOutputTraverser glslTraverse (infoSink, functionList, structList, usePrecision, transposeMatSwizzles);
root->traverse(&glslTraverse);
}

Просмотреть файл

@ -24,7 +24,7 @@ public:
TInfoSink& getInfoSink() { return infoSink; }
void TransformAST (TIntermNode* root);
void ProduceGLSL (TIntermNode* root, bool usePrecision);
void ProduceGLSL (TIntermNode* root, bool usePrecision, bool transposeMatSwizzles);
bool IsASTTransformed() const { return m_ASTTransformed; }
bool IsGlslProduced() const { return m_GlslProduced; }

Просмотреть файл

@ -267,7 +267,7 @@ int C_DECL Hlsl2Glsl_Parse( const ShHandle handle,
intermediate.outputTree(parseContext.treeRoot);
compiler->TransformAST (parseContext.treeRoot);
compiler->ProduceGLSL (parseContext.treeRoot, (options & ETranslateOpUsePrecision) ? true : false);
compiler->ProduceGLSL (parseContext.treeRoot, (options & ETranslateOpUsePrecision) ? true : false, (options & ETranslateOpTransposeMatrixSwizzles) ? true : false);
}
else if (!success)
{

Просмотреть файл

@ -121,6 +121,7 @@ enum TTranslateOptions
ETranslateOpNone = 0,
ETranslateOpIntermediate = (1<<0),
ETranslateOpUsePrecision = (1<<1),
ETranslateOpTransposeMatrixSwizzles = (1<<2),
};

Просмотреть файл

@ -0,0 +1,29 @@
#line 12
struct PS_INPUT {
vec4 position;
vec2 uv;
};
#line 7
struct VS_INPUT {
vec4 position;
vec2 uv;
};
uniform sampler2D diffuse_map;
vec4 ps_main( in PS_INPUT xlat_var_input );
#line 29
vec4 ps_main( in PS_INPUT xlat_var_input ) {
vec4 c = vec4(1.00000, 1.00000, 1.00000, 1.00000);
#line 30
c = texture2D( diffuse_map, xlat_var_input.uv);
return c;
}
varying vec2 xlv_TEXCOORD0;
void main() {
vec4 xl_retval;
PS_INPUT xlt_xlat_var_input;
xlt_xlat_var_input.position = vec4(0.0);
xlt_xlat_var_input.uv = vec2( xlv_TEXCOORD0);
xl_retval = ps_main( xlt_xlat_var_input);
gl_FragData[0] = vec4( xl_retval);
}

Просмотреть файл

@ -0,0 +1,29 @@
#line 12
struct PS_INPUT {
highp vec4 position;
highp vec2 uv;
};
#line 7
struct VS_INPUT {
highp vec4 position;
highp vec2 uv;
};
uniform sampler2D diffuse_map;
mediump vec4 ps_main( in PS_INPUT xlat_var_input );
#line 29
mediump vec4 ps_main( in PS_INPUT xlat_var_input ) {
mediump vec4 c = vec4(1.00000, 1.00000, 1.00000, 1.00000);
#line 30
c = texture2D( diffuse_map, xlat_var_input.uv);
return c;
}
varying highp vec2 xlv_TEXCOORD0;
void main() {
mediump vec4 xl_retval;
PS_INPUT xlt_xlat_var_input;
xlt_xlat_var_input.position = vec4(0.0);
xlt_xlat_var_input.uv = vec2( xlv_TEXCOORD0);
xl_retval = ps_main( xlt_xlat_var_input);
gl_FragData[0] = vec4( xl_retval);
}

Просмотреть файл

@ -0,0 +1,33 @@
float4x4 world;
float4x4 view;
float4x4 proj;
sampler2D diffuse_map;
struct VS_INPUT {
float4 position : POSITION;
float2 uv : TEXCOORD0;
};
struct PS_INPUT {
float4 position : POSITION;
float2 uv : TEXCOORD0;
};
PS_INPUT vs_main(VS_INPUT input) {
PS_INPUT o;
float4 wp = mul(input.position, world);
view._m30_m31_m32 = world._m30_m31_m32;
o.position = mul(mul(wp, view), proj);
o.uv = input.uv;
return o;
}
half4 ps_main(PS_INPUT input) : COLOR0 {
half4 c = half4(1, 1, 1, 1);
c = tex2D(diffuse_map, input.uv);
return c;
}

Просмотреть файл

@ -0,0 +1,42 @@
#line 12
struct PS_INPUT {
vec4 position;
vec2 uv;
};
#line 7
struct VS_INPUT {
vec4 position;
vec2 uv;
};
uniform mat4 proj;
uniform mat4 world;
uniform mat4 view;
mat4 xlat_mutable_view;
PS_INPUT vs_main( in VS_INPUT xlat_var_input );
#line 17
PS_INPUT vs_main( in VS_INPUT xlat_var_input ) {
vec4 wp;
PS_INPUT o;
wp = (xlat_var_input.position * world);
#line 21
vec3 xlat_swiztemp0 = world[3].xyz;
xlat_mutable_view[3][0] = xlat_swiztemp0.x;
xlat_mutable_view[3][1] = xlat_swiztemp0.y;
xlat_mutable_view[3][2] = xlat_swiztemp0.z;
o.position = ((wp * xlat_mutable_view) * proj);
o.uv = xlat_var_input.uv;
#line 26
return o;
}
varying vec2 xlv_TEXCOORD0;
void main() {
PS_INPUT xl_retval;
xlat_mutable_view = view;
VS_INPUT xlt_xlat_var_input;
xlt_xlat_var_input.position = vec4( gl_Vertex);
xlt_xlat_var_input.uv = vec2( gl_MultiTexCoord0);
xl_retval = vs_main( xlt_xlat_var_input);
gl_Position = vec4( xl_retval.position);
xlv_TEXCOORD0 = vec2( xl_retval.uv);
}

Просмотреть файл

@ -0,0 +1,42 @@
#line 12
struct PS_INPUT {
highp vec4 position;
highp vec2 uv;
};
#line 7
struct VS_INPUT {
highp vec4 position;
highp vec2 uv;
};
uniform highp mat4 proj;
uniform highp mat4 world;
uniform highp mat4 view;
highp mat4 xlat_mutable_view;
PS_INPUT vs_main( in VS_INPUT xlat_var_input );
#line 17
PS_INPUT vs_main( in VS_INPUT xlat_var_input ) {
highp vec4 wp;
PS_INPUT o;
wp = (xlat_var_input.position * world);
#line 21
vec3 xlat_swiztemp0 = world[3].xyz;
xlat_mutable_view[3][0] = xlat_swiztemp0.x;
xlat_mutable_view[3][1] = xlat_swiztemp0.y;
xlat_mutable_view[3][2] = xlat_swiztemp0.z;
o.position = ((wp * xlat_mutable_view) * proj);
o.uv = xlat_var_input.uv;
#line 26
return o;
}
varying highp vec2 xlv_TEXCOORD0;
void main() {
PS_INPUT xl_retval;
xlat_mutable_view = view;
VS_INPUT xlt_xlat_var_input;
xlt_xlat_var_input.position = vec4( gl_Vertex);
xlt_xlat_var_input.uv = vec2( gl_MultiTexCoord0);
xl_retval = vs_main( xlt_xlat_var_input);
gl_Position = vec4( xl_retval.position);
xlv_TEXCOORD0 = vec2( xl_retval.uv);
}

Просмотреть файл

@ -212,9 +212,11 @@ static bool CheckGLSL (bool vertex, const char* source)
return res;
}
static bool TestFile (bool vertex,
enum TestRun { VERTEX, FRAGMENT, BOTH, NUM_RUN_TYPES };
static bool TestFile (TestRun type,
const std::string& inputPath,
const std::string& outputPath,
const char* entryPoint,
bool usePrecision,
bool doCheckGLSL)
{
@ -225,7 +227,8 @@ static bool TestFile (bool vertex,
return false;
}
ShHandle parser = Hlsl2Glsl_ConstructCompiler (vertex ? EShLangVertex : EShLangFragment);
static const EShLanguage langs[] = {EShLangVertex, EShLangFragment};
ShHandle parser = Hlsl2Glsl_ConstructCompiler (langs[type]);
const char* sourceStr = input.c_str();
@ -255,7 +258,8 @@ static bool TestFile (bool vertex,
};
Hlsl2Glsl_SetUserAttributeNames (parser, kAttribSemantic, kAttribString, 1);
Hlsl2Glsl_UseUserVaryings (parser, true);
int translateOk = Hlsl2Glsl_Translate (parser, "main", options);
int translateOk = Hlsl2Glsl_Translate (parser, entryPoint, options);
const char* infoLog = Hlsl2Glsl_GetInfoLog( parser );
if (translateOk)
{
@ -273,7 +277,7 @@ static bool TestFile (bool vertex,
printf (" does not match expected output\n");
res = false;
}
if (doCheckGLSL && !CheckGLSL (vertex, text.c_str()))
if (doCheckGLSL && !CheckGLSL (type == VERTEX, text.c_str()))
{
res = false;
}
@ -295,6 +299,39 @@ static bool TestFile (bool vertex,
return res;
}
static bool TestCombinedFile(const std::string& inputPath,
bool usePrecision,
bool checkGL)
{
std::string outname = inputPath.substr (0,inputPath.size()-7);
std::string frag_out, vert_out;
if (usePrecision) {
vert_out = outname + "-vertex-outES.txt";
frag_out = outname + "-fragment-outES.txt";
} else {
vert_out = outname + "-vertex-out.txt";
frag_out = outname + "-fragment-out.txt";
}
bool res = TestFile(VERTEX, inputPath, vert_out, "vs_main", usePrecision, !usePrecision && checkGL);
return res & TestFile(FRAGMENT, inputPath, frag_out, "ps_main", usePrecision, !usePrecision && checkGL);
}
static bool TestFile (TestRun type,
const std::string& inputPath,
bool usePrecision,
bool checkGL)
{
std::string outname = inputPath.substr (0,inputPath.size()-7);
if (usePrecision) {
return TestFile(type, inputPath, outname + "-outES.txt", "main", true, false);
} else {
return TestFile(type, inputPath, outname + "-out.txt", "main", false, checkGL);
}
}
int main (int argc, const char** argv)
{
@ -312,10 +349,10 @@ int main (int argc, const char** argv)
std::string baseFolder = argv[1];
static const char* kTypeName[2] = { "vertex", "fragment" };
static const char* kTypeName[NUM_RUN_TYPES] = { "vertex", "fragment", "combined" };
size_t tests = 0;
size_t errors = 0;
for (int type = 0; type < 2; ++type)
for (int type = 0; type < NUM_RUN_TYPES; ++type)
{
printf ("testing %s...\n", kTypeName[type]);
std::string testFolder = baseFolder + "/" + kTypeName[type];
@ -326,28 +363,24 @@ int main (int argc, const char** argv)
for (size_t i = 0; i < n; ++i)
{
std::string inname = inputFiles[i];
bool ok = true;
printf ("test %s\n", inname.c_str());
std::string outname = inname.substr (0,inname.size()-7) + "-out.txt";
std::string outnameES = inname.substr (0,inname.size()-7) + "-outES.txt";
bool ok = TestFile (type==0,
testFolder + "/" + inname,
testFolder + "/" + outname,
false,
hasOpenGL);
if (type == BOTH) {
ok = TestCombinedFile(testFolder + "/" + inname, false, hasOpenGL);
if (ok)
{
ok = TestFile (type==0,
testFolder + "/" + inname,
testFolder + "/" + outnameES,
true,
false);
ok = TestCombinedFile(testFolder + "/" + inname, true, false);
} else {
ok = TestFile(TestRun(type), testFolder + "/" + inname, false, hasOpenGL);
if (ok)
ok = TestFile(TestRun(type), testFolder + "/" + inname, true, false);
}
if (!ok)
{
++errors;
}
}
}
clock_t time1 = clock();
float t = float(time1-time0) / float(CLOCKS_PER_SEC);
if (errors != 0)