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:
committed by
Guy Zadikario
parent
d61fb75ef8
commit
dd26774dac
@@ -7,10 +7,11 @@ translator_path := $(LOCAL_PATH)/..
|
||||
#exclude darwin builds
|
||||
ifeq (, $(findstring $(HOST_OS), darwin))
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
GLESv2Context.cpp \
|
||||
GLESv2Validate.cpp \
|
||||
GLESv2Imp.cpp
|
||||
LOCAL_SRC_FILES := \
|
||||
GLESv2Imp.cpp \
|
||||
GLESv2Context.cpp \
|
||||
GLESv2Validate.cpp \
|
||||
ShaderParser.cpp \
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
$(translator_path)/include \
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
|
||||
#include "GLESv2Context.h"
|
||||
|
||||
|
||||
|
||||
void GLESv2Context::init() {
|
||||
android::Mutex::Autolock mutex(s_lock);
|
||||
if(!m_initialized) {
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <utils/threads.h>
|
||||
|
||||
|
||||
|
||||
class GLESv2Context : public GLEScontext{
|
||||
public:
|
||||
void init();
|
||||
@@ -31,7 +32,6 @@ public:
|
||||
private:
|
||||
void sendArr(GLvoid* arr,GLenum arrayType,GLint size,GLsizei stride,int pointsIndex = -1);
|
||||
void initExtensionString();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <GLcommon/ThreadInfo.h>
|
||||
#include "GLESv2Context.h"
|
||||
#include "GLESv2Validate.h"
|
||||
#include "ShaderParser.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
@@ -313,11 +314,13 @@ GL_APICALL GLuint GL_APIENTRY glCreateProgram(void){
|
||||
}
|
||||
|
||||
GL_APICALL GLuint GL_APIENTRY glCreateShader(GLenum type){
|
||||
GET_CTX_RET(0);
|
||||
GET_CTX_V2_RET(0);
|
||||
const GLuint globalShaderName = ctx->dispatcher().glCreateShader(type);
|
||||
if(thrd->shareGroup.Ptr() && globalShaderName) {
|
||||
const GLuint localShaderName = thrd->shareGroup->genName(SHADER);
|
||||
ShaderParser* sp = new ShaderParser(type);
|
||||
thrd->shareGroup->replaceGlobalName(SHADER,localShaderName,globalShaderName);
|
||||
thrd->shareGroup->setObjectData(SHADER,localShaderName,ObjectDataPtr(sp));
|
||||
return localShaderName;
|
||||
}
|
||||
if(globalShaderName){
|
||||
@@ -381,7 +384,8 @@ GL_APICALL void GL_APIENTRY glDeleteProgram(GLuint program){
|
||||
GET_CTX();
|
||||
if(thrd->shareGroup.Ptr()) {
|
||||
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();
|
||||
if(thrd->shareGroup.Ptr()) {
|
||||
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){
|
||||
GET_CTX();
|
||||
ctx->dispatcher().glGetShaderPrecisionFormat(shadertype,precisiontype,range,precision);
|
||||
GET_CTX_V2();
|
||||
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){
|
||||
GET_CTX();
|
||||
if(thrd->shareGroup.Ptr()) {
|
||||
const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader);
|
||||
ctx->dispatcher().glGetShaderSource(globalShaderName,bufsize,length,source);
|
||||
//now need to convert it to match gles syntax
|
||||
const GLuint globalShaderName = thrd->shareGroup->getGlobalName(SHADER,shader);
|
||||
SET_ERROR_IF(globalShaderName == 0,GL_INVALID_VALUE);
|
||||
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){
|
||||
GET_CTX();
|
||||
GET_CTX_V2();
|
||||
SET_ERROR_IF(count < 0,GL_INVALID_VALUE);
|
||||
if(thrd->shareGroup.Ptr()){
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,3 +119,20 @@ bool GLESv2Validate::readPixelFrmt(GLenum format){
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ static bool hintTargetMode(GLenum target,GLenum mode);
|
||||
static bool capability(GLenum cap);
|
||||
static bool pixelStoreParam(GLenum param);
|
||||
static bool readPixelFrmt(GLenum format);
|
||||
|
||||
static bool shaderType(GLenum type);
|
||||
static bool precisionType(GLenum type);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -22,6 +22,45 @@ android::Mutex GLEScontext::s_lock;
|
||||
std::string* GLEScontext::s_glExtensions= NULL;
|
||||
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():
|
||||
m_initialized(false) ,
|
||||
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_UNITS,&maxTexUnits);
|
||||
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)
|
||||
s_glSupport.GL_EXT_TEXTURE_FORMAT_BGRA8888 = true;
|
||||
|
||||
@@ -22,6 +22,20 @@ typedef struct _textureUnitState {
|
||||
GLboolean enabled[NUM_TEXTURE_TARGETS];
|
||||
} 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 {
|
||||
GLSupport():maxLights(0),maxVertexAttribs(0),maxClipPlane(0),maxTexUnits(0),maxTexSize(0) , \
|
||||
GL_EXT_TEXTURE_FORMAT_BGRA8888(false), GL_EXT_FRAMEBUFFER_OBJECT(false), \
|
||||
@@ -34,6 +48,7 @@ struct GLSupport {
|
||||
int maxClipPlane;
|
||||
int maxTexUnits;
|
||||
int maxTexSize;
|
||||
Version glslVersion;
|
||||
bool GL_EXT_TEXTURE_FORMAT_BGRA8888;
|
||||
bool GL_EXT_FRAMEBUFFER_OBJECT;
|
||||
bool GL_ARB_VERTEX_BLEND;
|
||||
@@ -93,6 +108,7 @@ public:
|
||||
static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;}
|
||||
static int getMaxTexUnits(){return s_glSupport.maxTexUnits;}
|
||||
static int getMaxTexSize(){return s_glSupport.maxTexSize;}
|
||||
static Version glslVersion(){return s_glSupport.glslVersion;}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
Reference in New Issue
Block a user