From 2da542b598091f7d9ab6cb4088c4a90c8ebf1862 Mon Sep 17 00:00:00 2001 From: Yochai Shefi Simchon Date: Thu, 16 Jun 2011 16:30:13 +0300 Subject: [PATCH] 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). --- .../libs/Translator/GLES_CM/GLEScmImp.cpp | 87 +++++++++++++++++-- .../Translator/GLES_CM/GLEScmValidate.cpp | 1 + .../libs/Translator/GLcommon/GLEScontext.cpp | 7 ++ .../Translator/include/GLcommon/GLEScontext.h | 4 +- .../include/GLcommon/TranslatorIfaces.h | 6 +- 5 files changed, 95 insertions(+), 10 deletions(-) diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp index 41ad17505..ab4542b93 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmImp.cpp @@ -168,9 +168,14 @@ GL_API GLESiface* __translator_getIfaces(EGLiface* eglIface){ } -static TextureData* getTextureData(){ +static TextureData* getTextureData(unsigned int tex){ GET_CTX_RET(NULL); - unsigned int tex = ctx->getBindedTexture(); + + if(!thrd->shareGroup->isObject(TEXTURE,tex)) + { + return NULL; + } + TextureData *texData = NULL; ObjectDataPtr objData = thrd->shareGroup->getObjectData(TEXTURE,tex); if(!objData.Ptr()){ @@ -182,6 +187,13 @@ static TextureData* getTextureData(){ 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) { 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) { GET_CTX_RET(GL_FALSE) - if(texture && thrd->shareGroup.Ptr()){ - return thrd->shareGroup->isObject(TEXTURE,texture) ? GL_TRUE :GL_FALSE; - } - return ctx->dispatcher().glIsTexture(texture); + + if(texture == 0) // Special case + return GL_FALSE; + + TextureData* tex = getTextureData(texture); + return tex ? tex->wasBound : GL_FALSE; } GL_API GLenum GL_APIENTRY glGetError(void) { @@ -298,6 +312,9 @@ GL_API void GL_APIENTRY glBindTexture( GLenum target, GLuint texture) { } } ctx->setBindedTexture(texture); + TextureData* tex = getTextureData(texture); + tex->wasBound = true; + 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); + ctx->dispatcher().glTexImage2D(target,level,internalformat,width,height,border,format,type,pixels); + if (thrd->shareGroup.Ptr()){ TextureData *texData = getTextureData(); 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->border = border; 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) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)param)) + return; + ctx->dispatcher().glTexParameterf(target,pname,param); } GL_API void GL_APIENTRY glTexParameterfv( GLenum target, GLenum pname, const GLfloat *params) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)(*params))) + return; + if (pname==GL_TEXTURE_CROP_RECT_OES) { TextureData *texData = getTextureData(); 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) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)param)) + return; + ctx->dispatcher().glTexParameteri(target,pname,param); } GL_API void GL_APIENTRY glTexParameteriv( GLenum target, GLenum pname, const GLint *params) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)(*params))) + return; + if (pname==GL_TEXTURE_CROP_RECT_OES) { TextureData *texData = getTextureData(); 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) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)param)) + return; + ctx->dispatcher().glTexParameterf(target,pname,static_cast(param)); } GL_API void GL_APIENTRY glTexParameterxv( GLenum target, GLenum pname, const GLfixed *params) { GET_CTX() SET_ERROR_IF(!GLEScmValidate::texParams(target,pname),GL_INVALID_ENUM); + + if(handleMipmapGeneration(pname, (bool)(*params))) + return; + if (pname==GL_TEXTURE_CROP_RECT_OES) { TextureData *texData = getTextureData(); 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); 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) { diff --git a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp index 0ad576bbc..4e47cb984 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLES_CM/GLEScmValidate.cpp @@ -111,6 +111,7 @@ bool GLEScmValidate::texParams(GLenum target,GLenum pname) { case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: case GL_TEXTURE_CROP_RECT_OES: + case GL_GENERATE_MIPMAP: break; default: return false; diff --git a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp index 51cdc6f5e..1575fd92c 100644 --- a/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp +++ b/tools/emulator/opengl/host/libs/Translator/GLcommon/GLEScontext.cpp @@ -504,6 +504,9 @@ void GLEScontext::initCapsLocked(const GLubyte * extensionString) if (strstr(cstring,"GL_ARB_half_float_vertex ")!=NULL) 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) { @@ -565,6 +568,10 @@ bool GLEScontext::glGetIntegerv(GLenum pname, GLint *params) *params = m_elementBuffer; break; + case GL_TEXTURE_BINDING_2D: + *params = m_tex2DBind[m_activeTexture].texture; + break; + default: return false; } diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h index 03efdd7aa..a2d6f9394 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/GLEScontext.h @@ -41,7 +41,7 @@ struct GLSupport { GL_ARB_VERTEX_BLEND(false), GL_ARB_MATRIX_PALETTE(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_VERTEX(false) {} ; + GL_ARB_HALF_FLOAT_VERTEX(false),GL_SGIS_GENERATE_MIPMAP(false) {} ; int maxLights; int maxVertexAttribs; int maxClipPlane; @@ -58,6 +58,7 @@ struct GLSupport { bool GL_ARB_HALF_FLOAT_PIXEL; bool GL_NV_HALF_FLOAT; 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 getMaxTexSize(){return s_glSupport.maxTexSize;} 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 glGetBooleanv(GLenum pname, GLboolean *params); diff --git a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h index ee70f8a5b..b0d069888 100644 --- a/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h +++ b/tools/emulator/opengl/host/libs/Translator/include/GLcommon/TranslatorIfaces.h @@ -37,8 +37,8 @@ public: ~TextureData() { if (sourceEGLImage && eglImageDetach) (*eglImageDetach)(sourceEGLImage); } - TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0){ - memset(crop_rect,0,4*sizeof(int)); + TextureData():width(0),height(0),border(0),internalFormat(GL_RGBA),sourceEGLImage(0),wasBound(false),requiresAutoMipmap(false){ + memset(crop_rect,0,4*sizeof(int)); }; unsigned int width; @@ -46,6 +46,8 @@ public: unsigned int border; unsigned int internalFormat; unsigned int sourceEGLImage; + bool wasBound; + bool requiresAutoMipmap; int crop_rect[4]; void (*eglImageDetach)(unsigned int imageId); };