opengl translator: GLSL ES translation

There are some differences between GLSL/ES and Desktop
GLSL. This change translate the GLSL/ES shader source
to be compatible with the desktop GLSL language.

Change-Id: Ia6fdd6a90944926adcf440299b9ea3a4500d1eb1
This commit is contained in:
Amit Feller
2011-05-19 17:12:58 +03:00
committed by Guy Zadikario
parent d61fb75ef8
commit dd26774dac
10 changed files with 227 additions and 18 deletions

View File

@@ -7,10 +7,11 @@ translator_path := $(LOCAL_PATH)/..
#exclude darwin builds #exclude darwin builds
ifeq (, $(findstring $(HOST_OS), darwin)) ifeq (, $(findstring $(HOST_OS), darwin))
LOCAL_SRC_FILES := \ LOCAL_SRC_FILES := \
GLESv2Context.cpp \ GLESv2Imp.cpp \
GLESv2Validate.cpp \ GLESv2Context.cpp \
GLESv2Imp.cpp GLESv2Validate.cpp \
ShaderParser.cpp \
LOCAL_C_INCLUDES += \ LOCAL_C_INCLUDES += \
$(translator_path)/include \ $(translator_path)/include \

View File

@@ -16,6 +16,8 @@
#include "GLESv2Context.h" #include "GLESv2Context.h"
void GLESv2Context::init() { void GLESv2Context::init() {
android::Mutex::Autolock mutex(s_lock); android::Mutex::Autolock mutex(s_lock);
if(!m_initialized) { if(!m_initialized) {

View File

@@ -23,6 +23,7 @@
#include <utils/threads.h> #include <utils/threads.h>
class GLESv2Context : public GLEScontext{ class GLESv2Context : public GLEScontext{
public: public:
void init(); void init();
@@ -31,7 +32,6 @@ public:
private: private:
void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1); void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1);
void initExtensionString(); void initExtensionString();
}; };
#endif #endif

View File

@@ -27,6 +27,7 @@
#include <GLcommon/ThreadInfo.h> #include <GLcommon/ThreadInfo.h>
#include "GLESv2Context.h" #include "GLESv2Context.h"
#include "GLESv2Validate.h" #include "GLESv2Validate.h"
#include "ShaderParser.h"
extern "C" { extern "C" {
@@ -313,11 +314,13 @@ GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){
} }
GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){ GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){
GET_CTX_RET(0); GET_CTX_V2_RET(0);
const GLuint globalShaderName = ctx->dispatcher().glCreateShader(type); const GLuint globalShaderName = ctx->dispatcher().glCreateShader(type);
if(thrd->shareGroup.Ptr() && globalShaderName) { if(thrd->shareGroup.Ptr() && globalShaderName) {
const GLuint localShaderName = thrd->shareGroup->genName(SHADER); const GLuint localShaderName = thrd->shareGroup->genName(SHADER);
ShaderParser* sp = new ShaderParser(type);
thrd->shareGroup->replaceGlobalName(SHADER,localShaderName,globalShaderName); thrd->shareGroup->replaceGlobalName(SHADER,localShaderName,globalShaderName);
thrd->shareGroup->setObjectData(SHADER,localShaderName,ObjectDataPtr(sp));
return localShaderName; return localShaderName;
} }
if(globalShaderName){ if(globalShaderName){
@@ -381,7 +384,8 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){
GET_CTX(); GET_CTX();
if(thrd->shareGroup.Ptr()) { if(thrd->shareGroup.Ptr()) {
const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program); const GLuint globalProgramName = thrd->shareGroup->getGlobalName(SHADER,program);
ctx->dispatcher().glDeleteProgram(globalProgramName); thrd->shareGroup->deleteName(SHADER,program);
ctx->dispatcher().glDeleteProgram(program);
} }
} }
@@ -389,7 +393,8 @@ GL_APICALL void GL_APIENTRY glDeleteShader(GLuint shader){
GET_CTX(); GET_CTX();
if(thrd->shareGroup.Ptr()) { if(thrd->shareGroup.Ptr()) {
const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader);
ctx->dispatcher().glDeleteShader(globalShaderName); thrd->shareGroup->deleteName(SHADER,shader);
ctx->dispatcher().glDeleteShader(shader);
} }
} }
@@ -685,17 +690,28 @@ GL_APICALL void GL_APIENTRY glGetShaderInfoLog(GLuint shader, GLsizei bufsize,
} }
GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){ GL_APICALL void GL_APIENTRY glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision){
GET_CTX(); GET_CTX_V2();
ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision); SET_ERROR_IF(!(GLESv2Validate::shaderType(shadertype) && GLESv2Validate::precisionType(precisiontype)),GL_INVALID_ENUM);
if(ctx->glslVersion() < Version(1,30,10)){ //version 1.30.10 is the first version of GLSL Language containing precision qualifiers
range[0] = range[1] = 0;
precision = 0;
} else {
ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision);
}
} }
//TODO: may need to convert the source to fit to gles 2.0 shadders
GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){ GL_APICALL void GL_APIENTRY glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source){
GET_CTX(); GET_CTX();
if(thrd->shareGroup.Ptr()) { if(thrd->shareGroup.Ptr()) {
const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader);
ctx->dispatcher().glGetShaderSource(globalShaderName,bufsize,length,source); SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
//now need to convert it to match gles syntax ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader);
SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
const char* src = ((ShaderParser*)objData.Ptr())->getOriginalSrc();
int srcLength = strlen(src);
SET_ERROR_IF(bufsize < 0 || srcLength > bufsize,GL_INVALID_VALUE);
*length = srcLength;
strncpy(source,src,srcLength);
} }
} }
@@ -969,12 +985,17 @@ GL_APICALL void GL_APIENTRY glShaderBinary(GLsizei n, const GLuint* shaders, GL
} }
} }
//TODO: may need to change the source to match to GL shaders format
GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length){ GL_APICALL void GL_APIENTRY glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length){
GET_CTX(); GET_CTX_V2();
SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
if(thrd->shareGroup.Ptr()){ if(thrd->shareGroup.Ptr()){
const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader); const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader);
ctx->dispatcher().glShaderSource(globalShaderName,count,string,length); SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
ObjectDataPtr objData = thrd->shareGroup->getObjectData(SHADER,shader);
SET_ERROR_IF(!objData.Ptr(),GL_INVALID_OPERATION);
ShaderParser* sp = (ShaderParser*)objData.Ptr();
sp->setSrc(ctx->glslVersion(),count,string,length);
ctx->dispatcher().glShaderSource(globalShaderName,1,sp->parsedLines(),NULL);
} }
} }

View File

@@ -119,3 +119,20 @@ bool GLESv2Validate::readPixelFrmt(GLenum format){
return false; return false;
} }
bool GLESv2Validate::shaderType(GLenum type){
return type == GL_VERTEX_SHADER || type == GL_FRAGMENT_SHADER;
}
bool GLESv2Validate::precisionType(GLenum type){
switch(type){
case GL_LOW_FLOAT:
case GL_MEDIUM_FLOAT:
case GL_HIGH_FLOAT:
case GL_LOW_INT:
case GL_MEDIUM_INT:
case GL_HIGH_INT:
return true;
}
return false;
}

View File

@@ -30,7 +30,8 @@ static bool hintTargetMode(GLenum target,GLenum mode);
static bool capability(GLenum cap); static bool capability(GLenum cap);
static bool pixelStoreParam(GLenum param); static bool pixelStoreParam(GLenum param);
static bool readPixelFrmt(GLenum format); static bool readPixelFrmt(GLenum format);
static bool shaderType(GLenum type);
static bool precisionType(GLenum type);
}; };
#endif #endif

View File

@@ -0,0 +1,83 @@
#include "ShaderParser.h"
#include <string.h>
ShaderParser::ShaderParser():m_type(0),
m_src(NULL),
m_parsedLines(NULL){};
ShaderParser::ShaderParser(GLenum type):m_type(type),
m_parsedLines(NULL){};
void ShaderParser::setSrc(const Version& ver,GLsizei count,const GLchar** strings,const GLint* length){
for(int i = 0;i<count;i++){
m_src.append(strings[i]);
}
clearParsedSrc();
/*
version 1.30.10 is the first version of GLSL Language containing precision qualifiers
if the glsl version is less than 1.30.10 than we will use a shader parser which omits
all precision qualifiers from the shader source , otherwise we will use a shader parser
which set the default precisions to be the same as the default precisions of GLSL ES
*/
if(ver < Version(1,30,10)){
parseOmitPrecision();
} else {
parseExtendDefaultPrecision();
}
}
const char* ShaderParser::getOriginalSrc(){
return m_src.c_str();
}
void ShaderParser::parseOmitPrecision(){
//defines we need to add in order to Omit precisions qualifiers
static const GLchar defines[] = {
"#define GLES 1\n"
"#define lowp \n"
"#define mediump \n"
"#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);
}
void ShaderParser::parseExtendDefaultPrecision(){
//the precision lines which we need to add to the shader
static const GLchar extend[] = {
"#define GLES 1\n"
"precision lowp sampler2D;\n"
"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);
}
void ShaderParser::clearParsedSrc(){
if(m_parsedLines){
delete[] m_parsedLines;
}
}
ShaderParser::~ShaderParser(){
clearParsedSrc();
}

View File

@@ -0,0 +1,27 @@
#ifndef SHADER_PARSER_H
#define SHADER_PARSER_H
#include "GLESv2Context.h"
#include <string>
#include <GLES2/gl2.h>
#include <GLcommon/objectNameManager.h>
class ShaderParser:public ObjectData{
public:
ShaderParser();
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<const GLchar**>(&m_parsedLines);};
~ShaderParser();
private:
void parseOmitPrecision();
void parseExtendDefaultPrecision();
void clearParsedSrc();
GLenum m_type;
std::string m_src;
GLchar* m_parsedLines;
};
#endif

View File

@@ -22,6 +22,45 @@ android::Mutex GLEScontext::s_lock;
std::string* GLEScontext::s_glExtensions= NULL; std::string* GLEScontext::s_glExtensions= NULL;
GLSupport GLEScontext::s_glSupport; GLSupport GLEScontext::s_glSupport;
Version::Version():m_major(0),
m_minor(0),
m_release(0){};
Version::Version(int major,int minor,int release):m_major(major),
m_minor(minor),
m_release(release){};
Version::Version(const Version& ver):m_major(ver.m_major),
m_minor(ver.m_minor),
m_release(ver.m_release){}
Version::Version(const char* versionString){
m_release = 0;
if((!versionString) ||
((!(sscanf(versionString,"%d.%d" ,&m_major,&m_minor) == 2)) &&
(!(sscanf(versionString,"%d.%d.%d",&m_major,&m_minor,&m_release) == 3)))){
m_major = m_minor = 0; // the version is not in the right format
}
}
Version& Version::operator=(const Version& ver){
m_major = ver.m_major;
m_minor = ver.m_minor;
m_release = ver.m_release;
return *this;
}
bool Version::operator<(const Version& ver) const{
if(m_major < ver.m_major) return true;
if(m_major == ver.m_major){
if(m_minor < ver.m_minor) return true;
if(m_minor == ver.m_minor){
return m_release < ver.m_release;
}
}
return false;
}
GLEScontext::GLEScontext(): GLEScontext::GLEScontext():
m_initialized(false) , m_initialized(false) ,
m_activeTexture(0) , m_activeTexture(0) ,
@@ -378,6 +417,8 @@ void GLEScontext::initCapsLocked(const GLubyte * extensionString)
s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize); s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_SIZE,&s_glSupport.maxTexSize);
s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTexUnits); s_glDispatch.glGetIntegerv(GL_MAX_TEXTURE_UNITS,&maxTexUnits);
s_glSupport.maxTexUnits = maxTexUnits < MAX_TEX_UNITS ? maxTexUnits:MAX_TEX_UNITS; s_glSupport.maxTexUnits = maxTexUnits < MAX_TEX_UNITS ? maxTexUnits:MAX_TEX_UNITS;
const GLubyte* glslVersion = s_glDispatch.glGetString(GL_SHADING_LANGUAGE_VERSION);
s_glSupport.glslVersion = Version((const char*)(glslVersion));
if (strstr(cstring,"GL_EXT_bgra ")!=NULL) if (strstr(cstring,"GL_EXT_bgra ")!=NULL)
s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true; s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;

View File

@@ -22,6 +22,20 @@ typedef struct _textureUnitState {
GLboolean enabled[NUM_TEXTURE_TARGETS]; GLboolean enabled[NUM_TEXTURE_TARGETS];
} textureUnitState; } textureUnitState;
class Version{
public:
Version();
Version(int major,int minor,int release);
Version(const char* versionString);
Version(const Version& ver);
bool operator<(const Version& ver) const;
Version& operator=(const Version& ver);
private:
int m_major;
int m_minor;
int m_release;
};
struct GLSupport { struct GLSupport {
GLSupport():maxLights(0),maxVertexAttribs(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0) , \ GLSupport():maxLights(0),maxVertexAttribs(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0) , \
GL_EXT_TEXTURE_FORMAT_BGRA8888(false), GL_EXT_FRAMEBUFFER_OBJECT(false), \ GL_EXT_TEXTURE_FORMAT_BGRA8888(false), GL_EXT_FRAMEBUFFER_OBJECT(false), \
@@ -34,6 +48,7 @@ struct GLSupport {
int maxClipPlane; int maxClipPlane;
int maxTexUnits; int maxTexUnits;
int maxTexSize; int maxTexSize;
Version glslVersion;
bool GL_EXT_TEXTURE_FORMAT_BGRA8888; bool GL_EXT_TEXTURE_FORMAT_BGRA8888;
bool GL_EXT_FRAMEBUFFER_OBJECT; bool GL_EXT_FRAMEBUFFER_OBJECT;
bool GL_ARB_VERTEX_BLEND; bool GL_ARB_VERTEX_BLEND;
@@ -93,6 +108,7 @@ public:
static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;} static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;}
static int getMaxTexUnits(){return s_glSupport.maxTexUnits;} static int getMaxTexUnits(){return s_glSupport.maxTexUnits;}
static int getMaxTexSize(){return s_glSupport.maxTexSize;} static int getMaxTexSize(){return s_glSupport.maxTexSize;}
static Version glslVersion(){return s_glSupport.glslVersion;}
protected: protected: