Commit 76985f3c by Zhenyao Mo

Expose varying variables and also precision for all variables.

ANGLEBUG=457 R=alokp@chromium.org, kbr@chromium.org Review URL: https://codereview.appspot.com/12487043
parent 3cf1f4ea
......@@ -37,7 +37,7 @@ extern "C" {
// Version number for shader translation API.
// It is incremented everytime the API changes.
#define ANGLE_SH_VERSION 110
#define ANGLE_SH_VERSION 111
//
// The names of the following enums have been derived by replacing GL prefix
......@@ -109,12 +109,20 @@ typedef enum {
} ShDataType;
typedef enum {
SH_PRECISION_HIGHP = 0x5001,
SH_PRECISION_MEDIUMP = 0x5002,
SH_PRECISION_LOWP = 0x5003
} ShPrecisionType;
typedef enum {
SH_INFO_LOG_LENGTH = 0x8B84,
SH_OBJECT_CODE_LENGTH = 0x8B88, // GL_SHADER_SOURCE_LENGTH
SH_ACTIVE_UNIFORMS = 0x8B86,
SH_ACTIVE_UNIFORM_MAX_LENGTH = 0x8B87,
SH_ACTIVE_ATTRIBUTES = 0x8B89,
SH_ACTIVE_ATTRIBUTE_MAX_LENGTH = 0x8B8A,
SH_VARYINGS = 0x8BBB,
SH_VARYING_MAX_LENGTH = 0x8BBC,
SH_MAPPED_NAME_MAX_LENGTH = 0x6000,
SH_NAME_MAX_LENGTH = 0x6001,
SH_HASHED_NAME_MAX_LENGTH = 0x6002,
......@@ -128,7 +136,7 @@ typedef enum {
SH_VALIDATE_LOOP_INDEXING = 0x0001,
SH_INTERMEDIATE_TREE = 0x0002,
SH_OBJECT_CODE = 0x0004,
SH_ATTRIBUTES_UNIFORMS = 0x0008,
SH_VARIABLES = 0x0008,
SH_LINE_DIRECTIVES = 0x0010,
SH_SOURCE_PATH = 0x0020,
SH_MAP_LONG_VARIABLE_NAMES = 0x0040,
......@@ -294,9 +302,8 @@ COMPILER_EXPORT void ShDestruct(ShHandle handle);
// Can be queried by calling ShGetInfoLog().
// SH_OBJECT_CODE: Translates intermediate tree to glsl or hlsl shader.
// Can be queried by calling ShGetObjectCode().
// SH_ATTRIBUTES_UNIFORMS: Extracts attributes and uniforms.
// Can be queried by calling ShGetActiveAttrib() and
// ShGetActiveUniform().
// SH_VARIABLES: Extracts attributes, uniforms, and varyings.
// Can be queried by calling ShGetVariableInfo().
//
COMPILER_EXPORT int ShCompile(
const ShHandle handle,
......@@ -322,6 +329,9 @@ COMPILER_EXPORT int ShCompile(
// SH_ACTIVE_UNIFORM_MAX_LENGTH: the length of the longest active uniform
// variable name including the null
// termination character.
// SH_VARYINGS: the number of varying variables.
// SH_VARYING_MAX_LENGTH: the length of the longest varying variable name
// including the null termination character.
// SH_MAPPED_NAME_MAX_LENGTH: the length of the mapped variable name including
// the null termination character.
// SH_NAME_MAX_LENGTH: the max length of a user-defined name including the
......@@ -355,60 +365,39 @@ COMPILER_EXPORT void ShGetInfoLog(const ShHandle handle, char* infoLog);
// ShGetInfo with SH_OBJECT_CODE_LENGTH.
COMPILER_EXPORT void ShGetObjectCode(const ShHandle handle, char* objCode);
// Returns information about an active attribute variable.
// Returns information about a shader variable.
// Parameters:
// handle: Specifies the compiler
// index: Specifies the index of the attribute variable to be queried.
// variableType: Specifies the variable type; options include
// SH_ACTIVE_ATTRIBUTES, SH_ACTIVE_UNIFORMS, SH_VARYINGS.
// index: Specifies the index of the variable to be queried.
// length: Returns the number of characters actually written in the string
// indicated by name (excluding the null terminator) if a value other
// than NULL is passed.
// size: Returns the size of the attribute variable.
// type: Returns the data type of the attribute variable.
// size: Returns the size of the variable.
// type: Returns the data type of the variable.
// precision: Returns the precision of the variable.
// name: Returns a null terminated string containing the name of the
// attribute variable. It is assumed that name has enough memory to
// accomodate the attribute variable name. The size of the buffer
// required to store the attribute variable name can be obtained by
// calling ShGetInfo with SH_ACTIVE_ATTRIBUTE_MAX_LENGTH.
// variable. It is assumed that name has enough memory to accormodate
// the variable name. The size of the buffer required to store the
// variable name can be obtained by calling ShGetInfo with
// SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_ACTIVE_UNIFORM_MAX_LENGTH,
// SH_VARYING_MAX_LENGTH.
// mappedName: Returns a null terminated string containing the mapped name of
// the attribute variable, It is assumed that mappedName has enough
// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
// about the mapped name. If the name is not mapped, then name and
// mappedName are the same.
COMPILER_EXPORT void ShGetActiveAttrib(const ShHandle handle,
// the variable, It is assumed that mappedName has enough memory
// (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care about the
// mapped name. If the name is not mapped, then name and mappedName
// are the same.
COMPILER_EXPORT void ShGetVariableInfo(const ShHandle handle,
ShShaderInfo variableType,
int index,
size_t* length,
int* size,
ShDataType* type,
ShPrecisionType* precision,
char* name,
char* mappedName);
// Returns information about an active uniform variable.
// Parameters:
// handle: Specifies the compiler
// index: Specifies the index of the uniform variable to be queried.
// length: Returns the number of characters actually written in the string
// indicated by name (excluding the null terminator) if a value
// other than NULL is passed.
// size: Returns the size of the uniform variable.
// type: Returns the data type of the uniform variable.
// name: Returns a null terminated string containing the name of the
// uniform variable. It is assumed that name has enough memory to
// accomodate the uniform variable name. The size of the buffer required
// to store the uniform variable name can be obtained by calling
// ShGetInfo with SH_ACTIVE_UNIFORMS_MAX_LENGTH.
// mappedName: Returns a null terminated string containing the mapped name of
// the uniform variable, It is assumed that mappedName has enough
// memory (SH_MAPPED_NAME_MAX_LENGTH), or NULL if don't care
// about the mapped name. If the name is not mapped, then name and
// mappedName are the same.
COMPILER_EXPORT void ShGetActiveUniform(const ShHandle handle,
int index,
size_t* length,
int* size,
ShDataType* type,
char* name,
char* mappedName);
// Returns information about a name hashing entry from the latest compile.
// Parameters:
// handle: Specifies the compiler
......
#define MAJOR_VERSION 1
#define MINOR_VERSION 2
#define BUILD_VERSION 0
#define BUILD_REVISION 2436
#define BUILD_REVISION 2437
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -178,8 +178,8 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES) && hashFunction == NULL)
mapLongVariableNames(root);
if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS)) {
collectAttribsUniforms(root);
if (success && (compileOptions & SH_VARIABLES)) {
collectVariables(root);
if (compileOptions & SH_ENFORCE_PACKING_RESTRICTIONS) {
success = enforcePackingRestrictions();
if (!success) {
......@@ -358,9 +358,9 @@ bool TCompiler::enforceVertexShaderTimingRestrictions(TIntermNode* root)
return restrictor.numErrors() == 0;
}
void TCompiler::collectAttribsUniforms(TIntermNode* root)
void TCompiler::collectVariables(TIntermNode* root)
{
CollectAttribsUniforms collect(attribs, uniforms, hashFunction);
CollectVariables collect(attribs, uniforms, varyings, hashFunction);
root->traverse(&collect);
}
......
......@@ -70,6 +70,7 @@ public:
TInfoSink& getInfoSink() { return infoSink; }
const TVariableInfoList& getAttribs() const { return attribs; }
const TVariableInfoList& getUniforms() const { return uniforms; }
const TVariableInfoList& getVaryings() const { return varyings; }
int getMappedNameMaxLength() const;
ShHashFunction64 getHashFunction() const { return hashFunction; }
......@@ -90,8 +91,8 @@ protected:
// Returns true if the given shader does not exceed the minimum
// functionality mandated in GLSL 1.0 spec Appendix A.
bool validateLimitations(TIntermNode* root);
// Collect info for all attribs and uniforms.
void collectAttribsUniforms(TIntermNode* root);
// Collect info for all attribs, uniforms, varyings.
void collectVariables(TIntermNode* root);
// Map long variable names into shorter ones.
void mapLongVariableNames(TIntermNode* root);
// Translate to object code.
......@@ -142,6 +143,7 @@ private:
TInfoSink infoSink; // Output sink.
TVariableInfoList attribs; // Active attributes in the compiled shader.
TVariableInfoList uniforms; // Active uniforms in the compiled shader.
TVariableInfoList varyings; // Varyings in the compiled shader.
// Cached copy of the ref-counted singleton.
LongNameMap* longNameMap;
......
......@@ -21,14 +21,18 @@
// and the shading language compiler.
//
static bool checkActiveUniformAndAttribMaxLengths(const ShHandle handle,
size_t expectedValue)
static bool checkVariableMaxLengths(const ShHandle handle,
size_t expectedValue)
{
size_t activeUniformLimit = 0;
ShGetInfo(handle, SH_ACTIVE_UNIFORM_MAX_LENGTH, &activeUniformLimit);
size_t activeAttribLimit = 0;
ShGetInfo(handle, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, &activeAttribLimit);
return (expectedValue == activeUniformLimit && expectedValue == activeAttribLimit);
size_t varyingLimit = 0;
ShGetInfo(handle, SH_VARYING_MAX_LENGTH, &varyingLimit);
return (expectedValue == activeUniformLimit &&
expectedValue == activeAttribLimit &&
expectedValue == varyingLimit);
}
static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue)
......@@ -38,52 +42,6 @@ static bool checkMappedNameMaxLength(const ShHandle handle, size_t expectedValue
return (expectedValue == mappedNameMaxLength);
}
static void getVariableInfo(ShShaderInfo varType,
const ShHandle handle,
int index,
size_t* length,
int* size,
ShDataType* type,
char* name,
char* mappedName)
{
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;
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH and SH_ACTIVE_ATTRIBUTE_MAX_LENGTH
// in ShGetInfo, below.
size_t activeUniformAndAttribLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkActiveUniformAndAttribMaxLengths(handle, activeUniformAndAttribLength));
strncpy(name, varInfo.name.c_str(), activeUniformAndAttribLength);
name[activeUniformAndAttribLength - 1] = 0;
if (mappedName) {
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
}
}
//
// Driver must call this first, once, before doing any other compiler operations.
// Subsequent calls to this function are no-op.
......@@ -220,6 +178,12 @@ void ShGetInfo(const ShHandle handle, ShShaderInfo pname, size_t* params)
case SH_ACTIVE_ATTRIBUTE_MAX_LENGTH:
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
case SH_VARYINGS:
*params = compiler->getVaryings().size();
break;
case SH_VARYING_MAX_LENGTH:
*params = 1 + MAX_SYMBOL_NAME_LEN;
break;
case SH_MAPPED_NAME_MAX_LENGTH:
// Use longer length than MAX_SHORTENED_IDENTIFIER_SIZE to
// handle array and struct dereferences.
......@@ -277,28 +241,67 @@ void ShGetObjectCode(const ShHandle handle, char* objCode)
strcpy(objCode, infoSink.obj.c_str());
}
void ShGetActiveAttrib(const ShHandle handle,
void ShGetVariableInfo(const ShHandle handle,
ShShaderInfo varType,
int index,
size_t* length,
int* size,
ShDataType* type,
ShPrecisionType* precision,
char* name,
char* mappedName)
{
getVariableInfo(SH_ACTIVE_ATTRIBUTES,
handle, index, length, size, type, name, mappedName);
}
if (!handle || !size || !type || !name)
return;
ASSERT((varType == SH_ACTIVE_ATTRIBUTES) ||
(varType == SH_ACTIVE_UNIFORMS) ||
(varType == SH_VARYINGS));
void ShGetActiveUniform(const ShHandle handle,
int index,
size_t* length,
int* size,
ShDataType* type,
char* name,
char* mappedName)
{
getVariableInfo(SH_ACTIVE_UNIFORMS,
handle, index, length, size, type, name, mappedName);
TShHandleBase* base = reinterpret_cast<TShHandleBase*>(handle);
TCompiler* compiler = base->getAsCompiler();
if (compiler == 0)
return;
const TVariableInfoList& varList =
varType == SH_ACTIVE_ATTRIBUTES ? compiler->getAttribs() :
(varType == SH_ACTIVE_UNIFORMS ? compiler->getUniforms() :
compiler->getVaryings());
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;
switch (varInfo.precision) {
case EbpLow:
*precision = SH_PRECISION_LOWP;
break;
case EbpMedium:
*precision = SH_PRECISION_MEDIUMP;
break;
case EbpHigh:
*precision = SH_PRECISION_HIGHP;
break;
default:
ASSERT(false);
}
// This size must match that queried by
// SH_ACTIVE_UNIFORM_MAX_LENGTH, SH_ACTIVE_ATTRIBUTE_MAX_LENGTH, SH_VARYING_MAX_LENGTH
// in ShGetInfo, below.
size_t variableLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkVariableMaxLengths(handle, variableLength));
strncpy(name, varInfo.name.c_str(), variableLength);
name[variableLength - 1] = 0;
if (mappedName) {
// This size must match that queried by
// SH_MAPPED_NAME_MAX_LENGTH in ShGetInfo, below.
size_t maxMappedNameLength = 1 + MAX_SYMBOL_NAME_LEN;
ASSERT(checkMappedNameMaxLength(handle, maxMappedNameLength));
strncpy(mappedName, varInfo.mappedName.c_str(), maxMappedNameLength);
mappedName[maxMappedNameLength - 1] = 0;
}
}
void ShGetNameHashingEntry(const ShHandle handle,
......
......@@ -119,6 +119,7 @@ void getBuiltInVariableInfo(const TType& type,
varInfo.mappedName = mappedName.c_str();
varInfo.size = 1;
}
varInfo.precision = type.getPrecision();
varInfo.type = getVariableDataType(type);
infoList.push_back(varInfo);
}
......@@ -153,40 +154,42 @@ TVariableInfo::TVariableInfo(ShDataType type, int size)
{
}
CollectAttribsUniforms::CollectAttribsUniforms(TVariableInfoList& attribs,
TVariableInfoList& uniforms,
ShHashFunction64 hashFunction)
CollectVariables::CollectVariables(TVariableInfoList& attribs,
TVariableInfoList& uniforms,
TVariableInfoList& varyings,
ShHashFunction64 hashFunction)
: mAttribs(attribs),
mUniforms(uniforms),
mVaryings(varyings),
mHashFunction(hashFunction)
{
}
// We are only interested in attribute and uniform variable declaration.
void CollectAttribsUniforms::visitSymbol(TIntermSymbol*)
void CollectVariables::visitSymbol(TIntermSymbol*)
{
}
void CollectAttribsUniforms::visitConstantUnion(TIntermConstantUnion*)
void CollectVariables::visitConstantUnion(TIntermConstantUnion*)
{
}
bool CollectAttribsUniforms::visitBinary(Visit, TIntermBinary*)
bool CollectVariables::visitBinary(Visit, TIntermBinary*)
{
return false;
}
bool CollectAttribsUniforms::visitUnary(Visit, TIntermUnary*)
bool CollectVariables::visitUnary(Visit, TIntermUnary*)
{
return false;
}
bool CollectAttribsUniforms::visitSelection(Visit, TIntermSelection*)
bool CollectVariables::visitSelection(Visit, TIntermSelection*)
{
return false;
}
bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
bool CollectVariables::visitAggregate(Visit, TIntermAggregate* node)
{
bool visitChildren = false;
......@@ -199,10 +202,12 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
case EOpDeclaration: {
const TIntermSequence& sequence = node->getSequence();
TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
if (qualifier == EvqAttribute || qualifier == EvqUniform)
if (qualifier == EvqAttribute || qualifier == EvqUniform ||
qualifier == EvqVaryingIn || qualifier == EvqVaryingOut ||
qualifier == EvqInvariantVaryingIn || qualifier == EvqInvariantVaryingOut)
{
TVariableInfoList& infoList = qualifier == EvqAttribute ?
mAttribs : mUniforms;
TVariableInfoList& infoList = qualifier == EvqAttribute ? mAttribs :
(qualifier == EvqUniform ? mUniforms : mVaryings);
for (TIntermSequence::const_iterator i = sequence.begin();
i != sequence.end(); ++i)
{
......@@ -233,12 +238,12 @@ bool CollectAttribsUniforms::visitAggregate(Visit, TIntermAggregate* node)
return visitChildren;
}
bool CollectAttribsUniforms::visitLoop(Visit, TIntermLoop*)
bool CollectVariables::visitLoop(Visit, TIntermLoop*)
{
return false;
}
bool CollectAttribsUniforms::visitBranch(Visit, TIntermBranch*)
bool CollectVariables::visitBranch(Visit, TIntermBranch*)
{
return false;
}
......
......@@ -20,15 +20,17 @@ struct TVariableInfo {
TPersistString mappedName;
ShDataType type;
int size;
TPrecision precision;
};
typedef std::vector<TVariableInfo> TVariableInfoList;
// Traverses intermediate tree to collect all attributes and uniforms.
class CollectAttribsUniforms : public TIntermTraverser {
// Traverses intermediate tree to collect all attributes, uniforms, varyings.
class CollectVariables : public TIntermTraverser {
public:
CollectAttribsUniforms(TVariableInfoList& attribs,
TVariableInfoList& uniforms,
ShHashFunction64 hashFunction);
CollectVariables(TVariableInfoList& attribs,
TVariableInfoList& uniforms,
TVariableInfoList& varyings,
ShHashFunction64 hashFunction);
virtual void visitSymbol(TIntermSymbol*);
virtual void visitConstantUnion(TIntermConstantUnion*);
......@@ -42,6 +44,7 @@ public:
private:
TVariableInfoList& mAttribs;
TVariableInfoList& mUniforms;
TVariableInfoList& mVaryings;
ShHashFunction64 mHashFunction;
};
......
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