1.1 Translator conformance: fix texture issues

This fixes three issues:

1. glGet(GL_2d_TEXTURE_BINDING) should be handled by the translator rather
than by OpenGL.

2. glIsTexture shoud return GL_TRUE only if the texture was bound at some
point - add a wasBound member to the TextureData and maintain it.

3. glTexParameter(GL_GENERATE_MIPMAP) did not work. The first problem was
that it was not allowed by our validator - fixed. The next issue is that
this enum is not necessarily supported by the OpenGL implementation - it
is in OpenGL 2.x, but was replaced by an extension in 3.x. So in case the
extension does not exist, and GL_GENERATE_MIPMAP is required, save this info
in a new requiresAutoMipmap member of TextureData and call glGenerateMipmapExt
whenever glTex(Sub)Image2D is called.
There is a theoretical case where neither GL_GENERATE_MIPMAP nor glGenerateMipmap
is supported by the OpenGL implementation - this is not likely to happen, but
if we find such an implementation it might require implementing a mipmap
generation software algorithm (which is bad).
This commit is contained in:
Yochai Shefi Simchon
2011-06-16 16:30:13 +03:00
committed by Guy Zadickario
parent 635e929c44
commit 2da542b598
5 changed files with 95 additions and 10 deletions

View File

@@ -168,9 +168,14 @@ GL_API GLESiface* __translator_getIfaces(EGLiface* eglIface){
} }
static TextureData* getTextureData(){ static TextureData* getTextureData(unsigned int tex){
GET_CTX_RET(NULL); GET_CTX_RET(NULL);
unsigned int tex = ctx->getBindedTexture();
if(!thrd->shareGroup->isObject(TEXTURE,tex))
{
return NULL;
}
TextureData *texData = NULL; TextureData *texData = NULL;
ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex); ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex);
if(!objData.Ptr()){ if(!objData.Ptr()){
@@ -182,6 +187,13 @@ static TextureData* getTextureData(){
return texData; return texData;
} }
static TextureData* getTextureData(){
GET_CTX_RET(NULL);
unsigned int tex = ctx->getBindedTexture();
return getTextureData(tex);
}
GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) { GL_API GLboolean GL_APIENTRY glIsBuffer(GLuint buffer) {
GET_CTX_RET(GL_FALSE) GET_CTX_RET(GL_FALSE)
@@ -208,10 +220,12 @@ GL_API GLboolean GL_APIENTRY glIsEnabled( GLenum cap) {
GL_API GLboolean GL_APIENTRY glIsTexture( GLuint texture) { GL_API GLboolean GL_APIENTRY glIsTexture( GLuint texture) {
GET_CTX_RET(GL_FALSE) GET_CTX_RET(GL_FALSE)
if(texture && thrd->shareGroup.Ptr()){
return thrd->shareGroup->isObject(TEXTURE,texture) ? GL_TRUE :GL_FALSE; if(texture == 0) // Special case
} return GL_FALSE;
return ctx->dispatcher().glIsTexture(texture);
TextureData* tex = getTextureData(texture);
return tex ? tex->wasBound : GL_FALSE;
} }
GL_API GLenum GL_APIENTRY glGetError(void) { GL_API GLenum GL_APIENTRY glGetError(void) {
@@ -298,6 +312,9 @@ GL_API void GL_APIENTRY glBindTexture( GLenum target, GLuint texture) {
} }
} }
ctx->setBindedTexture(texture); ctx->setBindedTexture(texture);
TextureData* tex = getTextureData(texture);
tex->wasBound = true;
ctx->dispatcher().glBindTexture(target,globalTextureName); ctx->dispatcher().glBindTexture(target,globalTextureName);
} }
@@ -1398,6 +1415,8 @@ GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint interna
SET_ERROR_IF(!(GLEScmValidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION); SET_ERROR_IF(!(GLEScmValidate::pixelOp(format,type) && internalformat == ((GLint)format)),GL_INVALID_OPERATION);
ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels);
if (thrd->shareGroup.Ptr()){ if (thrd->shareGroup.Ptr()){
TextureData *texData = getTextureData(); TextureData *texData = getTextureData();
SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION); SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
@@ -1406,20 +1425,49 @@ GL_API void GL_APIENTRY glTexImage2D( GLenum target, GLint level, GLint interna
texData->height = height; texData->height = height;
texData->border = border; texData->border = border;
texData->internalFormat = internalformat; texData->internalFormat = internalformat;
if(texData->requiresAutoMipmap)
{
ctx->dispatcher().glGenerateMipmapEXT(target);
}
} }
} }
ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels); }
static bool handleMipmapGeneration(GLenum pname, bool param)
{
GET_CTX_RET(false)
if(pname == GL_GENERATE_MIPMAP && !ctx->isAutoMipmapSupported())
{
TextureData *texData = getTextureData();
if(texData)
{
texData->requiresAutoMipmap = param;
}
return true;
}
return false;
} }
GL_API void GL_APIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param) { GL_API void GL_APIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)param))
return;
ctx->dispatcher().glTexParameterf(target,pname,param); ctx->dispatcher().glTexParameterf(target,pname,param);
} }
GL_API void GL_APIENTRY glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) { GL_API void GL_APIENTRY glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)(*params)))
return;
if (pname==GL_TEXTURE_CROP_RECT_OES) { if (pname==GL_TEXTURE_CROP_RECT_OES) {
TextureData *texData = getTextureData(); TextureData *texData = getTextureData();
SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION); SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
@@ -1434,12 +1482,20 @@ GL_API void GL_APIENTRY glTexParameterfv( GLenum target, GLenum pname, const GL
GL_API void GL_APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param) { GL_API void GL_APIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)param))
return;
ctx->dispatcher().glTexParameteri(target,pname,param); ctx->dispatcher().glTexParameteri(target,pname,param);
} }
GL_API void GL_APIENTRY glTexParameteriv( GLenum target, GLenum pname, const GLint *params) { GL_API void GL_APIENTRY glTexParameteriv( GLenum target, GLenum pname, const GLint *params) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)(*params)))
return;
if (pname==GL_TEXTURE_CROP_RECT_OES) { if (pname==GL_TEXTURE_CROP_RECT_OES) {
TextureData *texData = getTextureData(); TextureData *texData = getTextureData();
SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION); SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
@@ -1454,12 +1510,20 @@ GL_API void GL_APIENTRY glTexParameteriv( GLenum target, GLenum pname, const GL
GL_API void GL_APIENTRY glTexParameterx( GLenum target, GLenum pname, GLfixed param) { GL_API void GL_APIENTRY glTexParameterx( GLenum target, GLenum pname, GLfixed param) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)param))
return;
ctx->dispatcher().glTexParameterf(target,pname,static_cast<GLfloat>(param)); ctx->dispatcher().glTexParameterf(target,pname,static_cast<GLfloat>(param));
} }
GL_API void GL_APIENTRY glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) { GL_API void GL_APIENTRY glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) {
GET_CTX() GET_CTX()
SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM);
if(handleMipmapGeneration(pname, (bool)(*params)))
return;
if (pname==GL_TEXTURE_CROP_RECT_OES) { if (pname==GL_TEXTURE_CROP_RECT_OES) {
TextureData *texData = getTextureData(); TextureData *texData = getTextureData();
SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION); SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
@@ -1480,6 +1544,15 @@ GL_API void GL_APIENTRY glTexSubImage2D( GLenum target, GLint level, GLint xoff
SET_ERROR_IF(!GLEScmValidate::pixelOp(format,type),GL_INVALID_OPERATION); SET_ERROR_IF(!GLEScmValidate::pixelOp(format,type),GL_INVALID_OPERATION);
ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels); ctx->dispatcher().glTexSubImage2D(target,level,xoffset,yoffset,width,height,format,type,pixels);
if (thrd->shareGroup.Ptr()){
TextureData *texData = getTextureData();
SET_ERROR_IF(texData==NULL,GL_INVALID_OPERATION);
if(texData && texData->requiresAutoMipmap)
{
ctx->dispatcher().glGenerateMipmapEXT(target);
}
}
} }
GL_API void GL_APIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z) { GL_API void GL_APIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z) {

View File

@@ -111,6 +111,7 @@ bool GLEScmValidate::texParams(GLenum target,GLenum pname) {
case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_S:
case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_T:
case GL_TEXTURE_CROP_RECT_OES: case GL_TEXTURE_CROP_RECT_OES:
case GL_GENERATE_MIPMAP:
break; break;
default: default:
return false; return false;

View File

@@ -504,6 +504,9 @@ void GLEScontext::initCapsLocked(const GLubyte * extensionString)
if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL) if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL)
s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true; s_glSupport.GL_ARB_HALF_FLOAT_VERTEX = true;
if (strstr(cstring,"GL_SGIS_generate_mipmap ")!=NULL)
s_glSupport.GL_SGIS_GENERATE_MIPMAP = true;
} }
bool GLEScontext::isTextureUnitEnabled(GLenum unit) { bool GLEScontext::isTextureUnitEnabled(GLenum unit) {
@@ -565,6 +568,10 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params)
*params = m_elementBuffer; *params = m_elementBuffer;
break; break;
case GL_TEXTURE_BINDING_2D:
*params = m_tex2DBind[m_activeTexture].texture;
break;
default: default:
return false; return false;
} }

View File

@@ -41,7 +41,7 @@ struct GLSupport {
GL_ARB_VERTEX_BLEND(false), GL_ARB_MATRIX_PALETTE(false), \ GL_ARB_VERTEX_BLEND(false), GL_ARB_MATRIX_PALETTE(false), \
GL_NV_PACKED_DEPTH_STENCIL(false) , GL_OES_READ_FORMAT(false), \ GL_NV_PACKED_DEPTH_STENCIL(false) , GL_OES_READ_FORMAT(false), \
GL_ARB_HALF_FLOAT_PIXEL(false), GL_NV_HALF_FLOAT(false), \ GL_ARB_HALF_FLOAT_PIXEL(false), GL_NV_HALF_FLOAT(false), \
GL_ARB_HALF_FLOAT_VERTEX(false) {} ; GL_ARB_HALF_FLOAT_VERTEX(false),GL_SGIS_GENERATE_MIPMAP(false) {} ;
int maxLights; int maxLights;
int maxVertexAttribs; int maxVertexAttribs;
int maxClipPlane; int maxClipPlane;
@@ -58,6 +58,7 @@ struct GLSupport {
bool GL_ARB_HALF_FLOAT_PIXEL; bool GL_ARB_HALF_FLOAT_PIXEL;
bool GL_NV_HALF_FLOAT; bool GL_NV_HALF_FLOAT;
bool GL_ARB_HALF_FLOAT_VERTEX; bool GL_ARB_HALF_FLOAT_VERTEX;
bool GL_SGIS_GENERATE_MIPMAP;
}; };
@@ -133,6 +134,7 @@ public:
static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;} static int getMaxClipPlanes(){return s_glSupport.maxClipPlane;}
static int getMaxTexSize(){return s_glSupport.maxTexSize;} static int getMaxTexSize(){return s_glSupport.maxTexSize;}
static Version glslVersion(){return s_glSupport.glslVersion;} static Version glslVersion(){return s_glSupport.glslVersion;}
static bool isAutoMipmapSupported(){return s_glSupport.GL_SGIS_GENERATE_MIPMAP;}
virtual bool glGetIntegerv(GLenum pname, GLint *params); virtual bool glGetIntegerv(GLenum pname, GLint *params);
virtual bool glGetBooleanv(GLenum pname, GLboolean *params); virtual bool glGetBooleanv(GLenum pname, GLboolean *params);

View File

@@ -37,8 +37,8 @@ public:
~TextureData() { ~TextureData() {
if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage); if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage);
} }
TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0){ TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0),wasBound(false),requiresAutoMipmap(false){
memset(crop_rect,0,4*sizeof(int)); memset(crop_rect,0,4*sizeof(int));
}; };
unsigned int width; unsigned int width;
@@ -46,6 +46,8 @@ public:
unsigned int border; unsigned int border;
unsigned int internalFormat; unsigned int internalFormat;
unsigned int sourceEGLImage; unsigned int sourceEGLImage;
bool wasBound;
bool requiresAutoMipmap;
int crop_rect[4]; int crop_rect[4];
void (*eglImageDetach)(unsigned int imageId); void (*eglImageDetach)(unsigned int imageId);
}; };