Implemented functionality to collect and return info for attributes and uniforms.

BUG=26
Review URL: http://codereview.appspot.com/2206046

git-svn-id: https://angleproject.googlecode.com/svn/trunk@440 736b8ea6-26fd-11df-bfd4-992fa37f6226
This commit is contained in:
alokp@chromium.org
2010-09-27 19:28:55 +00:00
parent 570bfc7c17
commit ee76f6af45
5 changed files with 296 additions and 30 deletions

View File

@@ -129,6 +129,7 @@ typedef enum {
} EShInfo;
typedef enum {
SH_NONE = 0,
SH_FLOAT = 0x1406,
SH_FLOAT_VEC2 = 0x8B50,
SH_FLOAT_VEC3 = 0x8B51,

View File

@@ -6,6 +6,7 @@
#include "GLSLANG/ShaderLang.h"
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
@@ -27,6 +28,7 @@ void usage();
void FreeFileData(char **data);
char** ReadFileData(char *fileName);
void LogMsg(char* msg, const char* name, const int num, const char* logName);
void PrintActiveVariables(ShHandle compiler, EShInfo varType);
//Added to accomodate the multiple strings.
int OutputMultipleStrings = 1;
@@ -60,6 +62,7 @@ int main(int argc, char* argv[])
ShHandle fragmentCompiler = 0;
char* buffer = 0;
int bufferLen = 0;
int numAttribs = 0, numUniforms = 0;
ShInitialize();
@@ -73,6 +76,7 @@ int main(int argc, char* argv[])
switch (argv[0][1]) {
case 'i': compileOptions |= EShOptIntermediateTree; break;
case 'o': compileOptions |= EShOptObjectCode; break;
case 'u': compileOptions |= EShOptAttribsUniforms; break;
default: failCode = EFailUsage;
}
} else {
@@ -99,6 +103,7 @@ int main(int argc, char* argv[])
ShGetInfoLog(compiler, buffer);
puts(buffer);
LogMsg("END", "COMPILER", numCompiles, "INFO LOG");
printf("\n\n");
if (compiled && (compileOptions & EShOptObjectCode)) {
LogMsg("BEGIN", "COMPILER", numCompiles, "OBJ CODE");
@@ -107,6 +112,18 @@ int main(int argc, char* argv[])
ShGetObjectCode(compiler, buffer);
puts(buffer);
LogMsg("END", "COMPILER", numCompiles, "OBJ CODE");
printf("\n\n");
}
if (compiled && (compileOptions & EShOptAttribsUniforms)) {
LogMsg("BEGIN", "COMPILER", numCompiles, "ACTIVE ATTRIBS");
PrintActiveVariables(compiler, SH_ACTIVE_ATTRIBUTES);
LogMsg("END", "COMPILER", numCompiles, "ACTIVE ATTRIBS");
printf("\n\n");
LogMsg("BEGIN", "COMPILER", numCompiles, "ACTIVE UNIFORMS");
PrintActiveVariables(compiler, SH_ACTIVE_UNIFORMS);
LogMsg("END", "COMPILER", numCompiles, "ACTIVE UNIFORMS");
printf("\n\n");
}
if (!compiled)
failCode = EFailCompile;
@@ -181,10 +198,11 @@ bool CompileFile(char *fileName, ShHandle compiler, int compileOptions)
//
void usage()
{
printf("Usage: translate [-i -o] file1 file2 ...\n"
printf("Usage: translate [-i -o -u] file1 file2 ...\n"
"Where: filename = filename ending in .frag or .vert\n"
" -i = print intermediate tree\n"
" -o = print translated code\n");
" -o = print translated code\n"
" -u = print active attribs and uniforms\n");
}
//
@@ -253,7 +271,60 @@ void FreeFileData(char** data)
void LogMsg(char* msg, const char* name, const int num, const char* logName)
{
printf(num >= 0 ? "#### %s %s %d %s ####\n" :
"#### %s %s INFO LOG ####\n", msg, name, num, logName);
printf("#### %s %s %d %s ####\n", msg, name, num, logName);
}
void PrintActiveVariables(ShHandle compiler, EShInfo varType)
{
int nameSize = 0;
switch (varType) {
case SH_ACTIVE_ATTRIBUTES:
ShGetInfo(compiler, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &nameSize);
break;
case SH_ACTIVE_UNIFORMS:
ShGetInfo(compiler, SH_ACTIVE_UNIFORM_MAX_LENGTH, &nameSize);
break;
default: assert(0);
}
if (nameSize <= 1) return;
char* name = (char*) malloc(nameSize * sizeof(char));
int activeVars = 0, size = 0;
EShDataType type;
char* typeName = NULL;
ShGetInfo(compiler, varType, &activeVars);
for (int i = 0; i < activeVars; ++i) {
switch (varType) {
case SH_ACTIVE_ATTRIBUTES:
ShGetActiveAttrib(compiler, i, NULL, &size, &type, name);
break;
case SH_ACTIVE_UNIFORMS:
ShGetActiveUniform(compiler, i, NULL, &size, &type, name);
break;
default: assert(0);
}
switch (type) {
case SH_FLOAT: typeName = "GL_FLOAT"; break;
case SH_FLOAT_VEC2: typeName = "GL_FLOAT_VEC2"; break;
case SH_FLOAT_VEC3: typeName = "GL_FLOAT_VEC3"; break;
case SH_FLOAT_VEC4: typeName = "GL_FLOAT_VEC4"; break;
case SH_INT: typeName = "GL_INT"; break;
case SH_INT_VEC2: typeName = "GL_INT_VEC2"; break;
case SH_INT_VEC3: typeName = "GL_INT_VEC3"; break;
case SH_INT_VEC4: typeName = "GL_INT_VEC4"; break;
case SH_BOOL: typeName = "GL_BOOL"; break;
case SH_BOOL_VEC2: typeName = "GL_BOOL_VEC2"; break;
case SH_BOOL_VEC3: typeName = "GL_BOOL_VEC3"; break;
case SH_BOOL_VEC4: typeName = "GL_BOOL_VEC4"; break;
case SH_FLOAT_MAT2: typeName = "GL_FLOAT_MAT2"; break;
case SH_FLOAT_MAT3: typeName = "GL_FLOAT_MAT3"; break;
case SH_FLOAT_MAT4: typeName = "GL_FLOAT_MAT4"; break;
case SH_SAMPLER_2D: typeName = "GL_SAMPLER_2D"; break;
case SH_SAMPLER_CUBE: typeName = "GL_SAMPLER_CUBE"; break;
default: assert(0);
}
printf("%d: name:%s type:%s size:%d\n", i, name, typeName, size);
}
free(name);
}

View File

@@ -11,17 +11,56 @@
#include "GLSLANG/ShaderLang.h"
#include "compiler/Initialize.h"
#include "compiler/InitializeDll.h"
#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
#include "compiler/SymbolTable.h"
//
// This is the platform independent interface between an OGL driver
// and the shading language compiler.
//
static int getVariableMaxLength(const TVariableInfoList& varList)
{
TString::size_type maxLen = 0;
for (TVariableInfoList::const_iterator i = varList.begin();
i != varList.end(); ++i)
{
maxLen = std::max(maxLen, i->name.size());
}
// Add 1 to include null-termination character.
return static_cast<int>(maxLen) + 1;
}
static void getVariableInfo(EShInfo varType,
const ShHandle handle,
int index,
int* length,
int* size,
EShDataType* type,
char* name)
{
if (!handle || !size || !type || !name)
return;
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
(varType == SH_ACTIVE_UNIFORMS));
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return;
const TVariableInfoList& varList = varType == SH_ACTIVE_ATTRIBUTES ?
compiler->getAttribs() : compiler->getUniforms();
if (index < 0 || index >= static_cast<int>(varList.size()))
return;
const TVariableInfo& varInfo = varList[index];
if (length) *length = varInfo.name.size();
*size = varInfo.size;
*type = varInfo.type;
strcpy(name, varInfo.name.c_str());
}
//
// Driver must call this first, once, before doing any other
// compiler operations.
@@ -151,16 +190,16 @@ void ShGetInfo(const ShHandle handle, EShInfo pname, int* params)
*params = compiler->getInfoSink().obj.size() + 1;
break;
case SH_ACTIVE_UNIFORMS:
UNIMPLEMENTED();
*params = compiler->getUniforms().size();
break;
case SH_ACTIVE_UNIFORM_MAX_LENGTH:
UNIMPLEMENTED();
*params = getVariableMaxLength(compiler->getUniforms());
break;
case SH_ACTIVE_ATTRIBUTES:
UNIMPLEMENTED();
*params = compiler->getAttribs().size();
break;
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
UNIMPLEMENTED();
*params = getVariableMaxLength(compiler->getAttribs());
break;
default: UNREACHABLE();
@@ -206,7 +245,8 @@ void ShGetActiveAttrib(const ShHandle handle,
EShDataType* type,
char* name)
{
UNIMPLEMENTED();
getVariableInfo(SH_ACTIVE_ATTRIBUTES,
handle, index, length, size, type, name);
}
void ShGetActiveUniform(const ShHandle handle,
@@ -216,5 +256,7 @@ void ShGetActiveUniform(const ShHandle handle,
EShDataType* type,
char* name)
{
UNIMPLEMENTED();
getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name);
}

View File

@@ -6,6 +6,128 @@
#include "compiler/VariableInfo.h"
static TString arrayBrackets(int index)
{
TStringStream stream;
stream << "[" << index << "]";
return stream.str();
}
// Returns the data type for an attribute or uniform.
static EShDataType getVariableDataType(const TType& type)
{
switch (type.getBasicType()) {
case EbtFloat:
if (type.isMatrix()) {
switch (type.getNominalSize()) {
case 2: return SH_FLOAT_MAT2;
case 3: return SH_FLOAT_MAT3;
case 4: return SH_FLOAT_MAT4;
default: UNREACHABLE();
}
} else if (type.isVector()) {
switch (type.getNominalSize()) {
case 2: return SH_FLOAT_VEC2;
case 3: return SH_FLOAT_VEC3;
case 4: return SH_FLOAT_VEC4;
default: UNREACHABLE();
}
} else {
return SH_FLOAT;
}
case EbtInt:
if (type.isMatrix()) {
UNREACHABLE();
} else if (type.isVector()) {
switch (type.getNominalSize()) {
case 2: return SH_INT_VEC2;
case 3: return SH_INT_VEC3;
case 4: return SH_INT_VEC4;
default: UNREACHABLE();
}
} else {
return SH_INT;
}
case EbtBool:
if (type.isMatrix()) {
UNREACHABLE();
} else if (type.isVector()) {
switch (type.getNominalSize()) {
case 2: return SH_BOOL_VEC2;
case 3: return SH_BOOL_VEC3;
case 4: return SH_BOOL_VEC4;
default: UNREACHABLE();
}
} else {
return SH_BOOL;
}
case EbtSampler2D: return SH_SAMPLER_2D;
case EbtSamplerCube: return SH_SAMPLER_CUBE;
default: UNREACHABLE();
}
return SH_NONE;
}
static void getBuiltInVariableInfo(const TType& type,
const TString& name,
TVariableInfoList& infoList);
static void getUserDefinedVariableInfo(const TType& type,
const TString& name,
TVariableInfoList& infoList);
// Returns info for an attribute or uniform.
static void getVariableInfo(const TType& type,
const TString& name,
TVariableInfoList& infoList)
{
if (type.getBasicType() == EbtStruct) {
if (type.isArray()) {
for (int i = 0; i < type.getArraySize(); ++i) {
TString lname = name + arrayBrackets(i);
getUserDefinedVariableInfo(type, lname, infoList);
}
} else {
getUserDefinedVariableInfo(type, name, infoList);
}
} else {
getBuiltInVariableInfo(type, name, infoList);
}
}
void getBuiltInVariableInfo(const TType& type,
const TString& name,
TVariableInfoList& infoList)
{
ASSERT(type.getBasicType() != EbtStruct);
TVariableInfo varInfo;
if (type.isArray()) {
varInfo.name = (name + "[0]").c_str();
varInfo.size = type.getArraySize();
} else {
varInfo.name = name.c_str();
varInfo.size = 1;
}
varInfo.type = getVariableDataType(type);
infoList.push_back(varInfo);
}
void getUserDefinedVariableInfo(const TType& type,
const TString& name,
TVariableInfoList& infoList)
{
ASSERT(type.getBasicType() == EbtStruct);
TString lname = name + ".";
const TTypeList* structure = type.getStruct();
for (size_t i = 0; i < structure->size(); ++i) {
const TType* fieldType = (*structure)[i].type;
getVariableInfo(*fieldType,
lname + fieldType->getFieldName(),
infoList);
}
}
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
TVariableInfoList& uniforms)
: mAttribs(attribs),
@@ -13,7 +135,7 @@ CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
{
}
// TODO(alokp): Implement these functions.
// We are only interested in attribute and uniform variable declaration.
void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
{
}
@@ -22,32 +144,62 @@ void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
{
}
bool CollectAttribsUniforms::visitBinary(Visit visit, TIntermBinary*)
bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
{
return false;
}
bool CollectAttribsUniforms::visitUnary(Visit visit, TIntermUnary*)
bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
{
return false;
}
bool CollectAttribsUniforms::visitSelection(Visit visit, TIntermSelection*)
bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
{
return false;
}
bool CollectAttribsUniforms::visitAggregate(Visit visit, TIntermAggregate*)
bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
{
bool visitChildren = false;
switch (node->getOp())
{
case EOpSequence:
// We need to visit sequence children to get to variable declarations.
visitChildren = true;
break;
case EOpDeclaration: {
const TIntermSequence& sequence = node->getSequence();
const TIntermSymbol* variable = sequence.front()->getAsSymbolNode();
const TType& type = variable->getType();
TQualifier qualifier = type.getQualifier();
if (qualifier == EvqAttribute || qualifier == EvqUniform)
{
TVariableInfoList& infoList = qualifier == EvqAttribute ?
mAttribs : mUniforms;
for (TIntermSequence::const_iterator i = sequence.begin();
i != sequence.end(); ++i)
{
variable = (*i)->getAsSymbolNode();
getVariableInfo(variable->getType(), variable->getSymbol(),
infoList);
}
}
break;
}
default: break;
}
return visitChildren;
}
bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
{
return false;
}
bool CollectAttribsUniforms::visitLoop(Visit visit, TIntermLoop*)
{
return false;
}
bool CollectAttribsUniforms::visitBranch(Visit visit, TIntermBranch*)
bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
{
return false;
}

View File

@@ -24,12 +24,12 @@ public:
virtual void visitSymbol(TIntermSymbol*);
virtual void visitConstantUnion(TIntermConstantUnion*);
virtual bool visitBinary(Visit visit, TIntermBinary*);
virtual bool visitUnary(Visit visit, TIntermUnary*);
virtual bool visitSelection(Visit visit, TIntermSelection*);
virtual bool visitAggregate(Visit visit, TIntermAggregate*);
virtual bool visitLoop(Visit visit, TIntermLoop*);
virtual bool visitBranch(Visit visit, TIntermBranch*);
virtual bool visitBinary(Visit, TIntermBinary*);
virtual bool visitUnary(Visit, TIntermUnary*);
virtual bool visitSelection(Visit, TIntermSelection*);
virtual bool visitAggregate(Visit, TIntermAggregate*);
virtual bool visitLoop(Visit, TIntermLoop*);
virtual bool visitBranch(Visit, TIntermBranch*);
private:
TVariableInfoList& mAttribs;