From 715c4898df53ec8b419ba0c48247e715bc0a8acf Mon Sep 17 00:00:00 2001 From: Liran Date: Thu, 21 Jul 2011 16:52:56 +0300 Subject: [PATCH] 2.0 translator: workaround for nVidia "bug" This is not really a bug, but the nVidia shader compiler is much more liberal than the GLSL spec, and allows compilation of shaders which do not comply with the spec. This is an issue for passing the conformance tests, but more importantly it will allow bad shader written by the app developer to pass on the emulator and then to fail on the device. Adding "#version 100" definition to the head of a shader source disables this liberal behavior. For now this is activated in run time by the "NV_WAR" environment variable. Change-Id: I1c322d4221d313d3ee70592bc15ea0e340853990 --- .../libs/Translator/GLES_V2/ShaderParser.cpp | 53 ++++++++++--------- .../libs/Translator/GLES_V2/ShaderParser.h | 5 +- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp index 0a8390fe5..784c0d3ea 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.cpp @@ -3,18 +3,23 @@ ShaderParser::ShaderParser():ObjectData(SHADER_DATA), m_type(0), - m_src(NULL), - m_parsedLines(NULL){}; + m_parsedLines(NULL) {}; ShaderParser::ShaderParser(GLenum type):ObjectData(SHADER_DATA), m_type(type), - m_parsedLines(NULL){}; + m_parsedLines(NULL) {}; void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length){ for(int i = 0;i (&m_parsedLines); +}; const char* ShaderParser::getOriginalSrc(){ return m_src.c_str(); } +void ShaderParser::parseOriginalSrc() { + m_parsedSrc+=m_src; +} + +void ShaderParser::parseGLSLversion() { + //if no version definition is found + if (m_src.find("#version ", 0) == std::string::npos) { + m_parsedSrc += "#version 100\n"; + } +} + void ShaderParser::parseOmitPrecision(){ //defines we need to add in order to Omit precisions qualifiers @@ -47,16 +69,7 @@ void ShaderParser::parseOmitPrecision(){ "#define highp \n" "#define precision \n" }; - - //the lengths of defines we need to add in order to Omit precisions qualifiers - static GLuint definesLength = strlen(defines); - - const GLchar* origSrc = m_src.c_str(); - unsigned int origLength = strlen(origSrc); - - m_parsedLines = new GLchar[origLength + definesLength + 1]; - strncpy(m_parsedLines,defines,definesLength); - strcpy(m_parsedLines+definesLength,origSrc); + m_parsedSrc+=defines; } void ShaderParser::parseExtendDefaultPrecision(){ @@ -68,21 +81,11 @@ void ShaderParser::parseExtendDefaultPrecision(){ "precision lowp samplerCube;\n" }; - //the length of the precision lines which we need to add to the shader - static GLint extendLength = strlen(extend); - - const GLchar* origSrc = m_src.c_str(); - unsigned int origLength = strlen(origSrc); - - m_parsedLines = new GLchar[origLength + extendLength + 1]; - strncpy(m_parsedLines,extend,extendLength); - strcpy(m_parsedLines+extendLength,origSrc); + m_parsedSrc+=extend; } void ShaderParser::clearParsedSrc(){ - if(m_parsedLines){ - delete[] m_parsedLines; - } + m_parsedSrc.clear(); } GLenum ShaderParser::getType() { diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h index 4f32f908b..ca2c69fa9 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h +++ b/tools/emulator/opengl/host/libs/Translator/GLES_V2/ShaderParser.h @@ -12,17 +12,20 @@ public: ShaderParser(GLenum type); void setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length); const char* getOriginalSrc(); - const GLchar** parsedLines(){return const_cast(&m_parsedLines);}; + const GLchar** parsedLines(); GLenum getType(); ~ShaderParser(); private: + void parseOriginalSrc(); + void parseGLSLversion(); void parseOmitPrecision(); void parseExtendDefaultPrecision(); void clearParsedSrc(); GLenum m_type; std::string m_src; + std::string m_parsedSrc; GLchar* m_parsedLines; }; #endif