am 255bdd3f: Merge "opengles emulator: fix shader parser precision qualifiers"
* commit '255bdd3f1b68c98bdeeea7006132b61e9bade1cb': opengles emulator: fix shader parser precision qualifiers
This commit is contained in:
@@ -1296,11 +1296,16 @@ GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, G
|
||||
SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
|
||||
SET_ERROR_IF(objData.Ptr()->getDataType()!=SHADER_DATA,GL_INVALID_OPERATION);
|
||||
const char* src = ((ShaderParser*)objData.Ptr())->getOriginalSrc();
|
||||
int srcLength = strlen(src);
|
||||
int srcLength = 0;
|
||||
if (src) {
|
||||
srcLength = strlen(src);
|
||||
}
|
||||
|
||||
int returnLength = bufsize<srcLength ? bufsize-1 : srcLength;
|
||||
strncpy(source,src, returnLength);
|
||||
source[returnLength] = '\0';
|
||||
if (returnLength) {
|
||||
strncpy(source,src, returnLength);
|
||||
source[returnLength] = '\0';
|
||||
}
|
||||
|
||||
if (length)
|
||||
*length = returnLength;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
ShaderParser::ShaderParser():ObjectData(SHADER_DATA),
|
||||
m_type(0),
|
||||
m_originalSrc(NULL),
|
||||
m_parsedLines(NULL) {
|
||||
m_infoLog = new GLchar[1];
|
||||
m_infoLog[0] = '\0';
|
||||
@@ -10,6 +11,7 @@ ShaderParser::ShaderParser():ObjectData(SHADER_DATA),
|
||||
|
||||
ShaderParser::ShaderParser(GLenum type):ObjectData(SHADER_DATA),
|
||||
m_type(type),
|
||||
m_originalSrc(NULL),
|
||||
m_parsedLines(NULL) {
|
||||
|
||||
m_infoLog = new GLchar[1];
|
||||
@@ -20,6 +22,11 @@ void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** string
|
||||
for(int i = 0;i<count;i++){
|
||||
m_src.append(strings[i]);
|
||||
}
|
||||
//store original source
|
||||
if (m_originalSrc)
|
||||
free(m_originalSrc);
|
||||
m_originalSrc = strdup(m_src.c_str());
|
||||
|
||||
clearParsedSrc();
|
||||
|
||||
// parseGLSLversion must be called first since #version should be the
|
||||
@@ -42,7 +49,7 @@ void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** string
|
||||
//XXX: Until proved otherwise, glsl doesn't know/use those precision macros, so we omit then
|
||||
parseOmitPrecision();
|
||||
#endif
|
||||
|
||||
parseLineNumbers();
|
||||
parseOriginalSrc();
|
||||
}
|
||||
const GLchar** ShaderParser::parsedLines() {
|
||||
@@ -51,7 +58,12 @@ const GLchar** ShaderParser::parsedLines() {
|
||||
};
|
||||
|
||||
const char* ShaderParser::getOriginalSrc(){
|
||||
return m_src.c_str();
|
||||
return m_originalSrc;
|
||||
}
|
||||
|
||||
void ShaderParser::parseLineNumbers()
|
||||
{
|
||||
m_parsedSrc += "#line 1\n";
|
||||
}
|
||||
|
||||
void ShaderParser::parseOriginalSrc() {
|
||||
@@ -173,9 +185,107 @@ void ShaderParser::parseOmitPrecision(){
|
||||
"#define lowp \n"
|
||||
"#define mediump \n"
|
||||
"#define highp \n"
|
||||
"#define precision \n"
|
||||
};
|
||||
m_parsedSrc+=defines;
|
||||
|
||||
//
|
||||
// parse the source and blank out precision statements
|
||||
// which has the following syntax:
|
||||
// precision {qualifier} {type};
|
||||
// where {qualifier} is one of lowp,mediump or hightp
|
||||
// type is any valid GLES defined type (we do not check that here!)
|
||||
// NOTE: This is needed in order to workaround driver bug in
|
||||
// Intel/Linux where the compiler does not get statement like
|
||||
// "float;", otherwise we could just define a macro named
|
||||
// precision to be empty.
|
||||
//
|
||||
const char *src = m_src.c_str();
|
||||
|
||||
enum {
|
||||
PRECISION,
|
||||
QUALIFIER,
|
||||
SEMICOLON
|
||||
} statementState = PRECISION;
|
||||
const char *precision = NULL;
|
||||
const char *delimiter = NULL;
|
||||
|
||||
enum {
|
||||
PARSE_NONE,
|
||||
PARSE_IN_C_COMMENT,
|
||||
PARSE_IN_LINE_COMMENT
|
||||
} parseState = PARSE_NONE;
|
||||
const char *c = src;
|
||||
const char *t = NULL;
|
||||
|
||||
#define IS_DELIMITER(c) ( (c) == ' ' || (c) == '\t' || (c) == '\r' || (c) == '\n' )
|
||||
#define IS_TOKEN_START(c) ( ((c) >= 'a' && (c) <='z') || ((c) >= 'A' && (c) <= 'Z') )
|
||||
#define IS_TOKEN_DELIMITER(c) ( IS_DELIMITER(c) || (c) == ';' )
|
||||
|
||||
while( c && *c != '\0') {
|
||||
if (parseState == PARSE_IN_C_COMMENT) {
|
||||
if (*c == '*' && *(c+1) == '/') {
|
||||
parseState = PARSE_NONE;
|
||||
c += 2;
|
||||
}
|
||||
else c++;
|
||||
}
|
||||
else if (parseState == PARSE_IN_LINE_COMMENT) {
|
||||
if (*c == '\n') {
|
||||
parseState = PARSE_NONE;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
else if (*c == '/' && *(c+1) == '/') {
|
||||
parseState = PARSE_IN_LINE_COMMENT;
|
||||
c += 2;
|
||||
}
|
||||
else if (*c == '/' && *(c+1) == '*') {
|
||||
parseState = PARSE_IN_C_COMMENT;
|
||||
c += 2;
|
||||
}
|
||||
else if (t && IS_TOKEN_DELIMITER(*c)) {
|
||||
int tokenLen = c - t;
|
||||
switch (statementState) {
|
||||
case PRECISION:
|
||||
if (tokenLen == 9 && !strncmp(t,"precision",9)) {
|
||||
statementState = QUALIFIER;
|
||||
precision = t;
|
||||
}
|
||||
break;
|
||||
case QUALIFIER:
|
||||
if ((tokenLen == 4 && !strncmp(t,"lowp",4)) ||
|
||||
(tokenLen == 7 && !strncmp(t,"mediump",7)) ||
|
||||
(tokenLen == 5 && !strncmp(t,"highp",5))) {
|
||||
statementState = SEMICOLON;
|
||||
}
|
||||
else {
|
||||
statementState = PRECISION;
|
||||
}
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (*c == ';') {
|
||||
for (char *r = (char *)precision; r<=c ; ++r) {
|
||||
*r = ' '; //blank the character
|
||||
}
|
||||
}
|
||||
statementState = PRECISION; //search for the next precision line
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
c++;
|
||||
t = NULL;
|
||||
}
|
||||
else if (IS_DELIMITER(*c)) {
|
||||
c++;
|
||||
}
|
||||
else {
|
||||
if (!t && IS_TOKEN_START(*c)) {
|
||||
t = c;
|
||||
}
|
||||
c++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ShaderParser::parseExtendDefaultPrecision(){
|
||||
@@ -211,5 +321,7 @@ GLchar* ShaderParser::getInfoLog()
|
||||
|
||||
ShaderParser::~ShaderParser(){
|
||||
clearParsedSrc();
|
||||
if (m_originalSrc)
|
||||
free(m_originalSrc);
|
||||
delete[] m_infoLog;
|
||||
}
|
||||
|
||||
@@ -25,9 +25,11 @@ private:
|
||||
void parseBuiltinConstants();
|
||||
void parseOmitPrecision();
|
||||
void parseExtendDefaultPrecision();
|
||||
void parseLineNumbers();
|
||||
void clearParsedSrc();
|
||||
|
||||
GLenum m_type;
|
||||
char* m_originalSrc;
|
||||
std::string m_src;
|
||||
std::string m_parsedSrc;
|
||||
GLchar* m_parsedLines;
|
||||
|
||||
Reference in New Issue
Block a user