From b5c03d5734c5eeb8d65aebeccbe9f0d15b3ac2e9 Mon Sep 17 00:00:00 2001 From: Lingfeng Yang Date: Wed, 7 Sep 2016 14:40:03 -0700 Subject: [PATCH] [CTS][deqp] avoid rebinding textures in glTex(Sub)Image2D bug: 31307568 If we stop rebinding the same texture every call, we can fix 4 CTS dEQP failures on Quadro K2200 / K600's: dEQP-GLES2.functional.texture.specification.random_teximage2d.2d_3 dEQP-GLES2.functional.texture.specification.random_teximage2d.2d_7 dEQP-GLES2.functional.texture.specification.random_teximage2d.2d_8 dEQP-GLES2.functional.texture.specification.random_teximage2d.2d_9 These random (as in seeded only once, same "random" config everytime) texture tests attempt to construct mipmaps in random order using repeated calls to glTexImage2D. Four of these tests fail because they construct the texture mipmaps in just the wrong order to expose what seems like a NVIDIA driver bug: if we attempt to glBindTexture the "same" texture before each glTexImage2D AND do not start with mipmap level 0, we get a corrupted texture for what seems like all mipmap levels that were specified before mipmap level 0 was specified. This CL avoids calling glBindTexture when we didn't need to overrride the GL_TEXTURE_2D texture on the host. The previous behavior seems unresonable, in fact: it is also not a high quality thing to do if we always issue glBindTexture on host when "restoring" a texture target that has NOT been overriden. No regression has been detected in CTS dEQP GLES2, EGL / CTS camera. It should also be a slight performance increase for apps that heavily thrash glTexImage2D. Change-Id: I6910d93733cb682737f49aff448097e263cd675b --- system/GLESv2/gl2.cpp | 4 ++-- system/GLESv2_enc/GL2Encoder.cpp | 38 ++++++++++++++++++++++---------------- system/GLESv2_enc/GL2Encoder.h | 3 ++- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/system/GLESv2/gl2.cpp b/system/GLESv2/gl2.cpp index 5aaac5f..ec82046 100644 --- a/system/GLESv2/gl2.cpp +++ b/system/GLESv2/gl2.cpp @@ -75,14 +75,14 @@ void glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES img) ctx->override2DTextureTarget(target); rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else if (image->target == EGL_GL_TEXTURE_2D_KHR) { GET_CONTEXT; ctx->override2DTextureTarget(target); GLeglImageOES hostImage = reinterpret_cast((intptr_t)image->host_egl_image); ctx->m_glEGLImageTargetTexture2DOES_enc(self, target, hostImage); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } } diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp index 97557c9..a32fcdb 100755 --- a/system/GLESv2_enc/GL2Encoder.cpp +++ b/system/GLESv2_enc/GL2Encoder.cpp @@ -1315,7 +1315,7 @@ void GL2Encoder::s_glGetTexParameterfv(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glGetTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glGetTexParameterfv_enc(ctx, target, pname, params); } @@ -1336,7 +1336,7 @@ void GL2Encoder::s_glGetTexParameteriv(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glGetTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glGetTexParameteriv_enc(ctx, target, pname, params); } @@ -1373,7 +1373,7 @@ void GL2Encoder::s_glTexParameterf(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glTexParameterf_enc(ctx, GL_TEXTURE_2D, pname, param); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexParameterf_enc(ctx, target, pname, param); } @@ -1392,7 +1392,7 @@ void GL2Encoder::s_glTexParameterfv(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glTexParameterfv_enc(ctx, GL_TEXTURE_2D, pname, params); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexParameterfv_enc(ctx, target, pname, params); } @@ -1411,7 +1411,7 @@ void GL2Encoder::s_glTexParameteri(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glTexParameteri_enc(ctx, GL_TEXTURE_2D, pname, param); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexParameteri_enc(ctx, target, pname, param); } @@ -1431,7 +1431,7 @@ void GL2Encoder::s_glTexImage2D(void* self, GLenum target, GLint level, ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, height, border, format, type, pixels); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexImage2D_enc(ctx, target, level, internalformat, width, height, border, format, type, pixels); @@ -1448,7 +1448,7 @@ void GL2Encoder::s_glTexSubImage2D(void* self, GLenum target, GLint level, ctx->override2DTextureTarget(target); ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexSubImage2D_enc(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels); @@ -1468,26 +1468,32 @@ void GL2Encoder::s_glTexParameteriv(void* self, if (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) { ctx->override2DTextureTarget(target); ctx->m_glTexParameteriv_enc(ctx, GL_TEXTURE_2D, pname, params); - ctx->restore2DTextureTarget(); + ctx->restore2DTextureTarget(target); } else { ctx->m_glTexParameteriv_enc(ctx, target, pname, params); } } +bool GL2Encoder::texture2DNeedsOverride(GLenum target) const { + return (target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && + target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); +} + void GL2Encoder::override2DTextureTarget(GLenum target) { - if ((target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES) && - target != m_state->getPriorityEnabledTarget(GL_TEXTURE_2D)) { - m_glBindTexture_enc(this, GL_TEXTURE_2D, - m_state->getBoundTexture(target)); + if (texture2DNeedsOverride(target)) { + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture(target)); } } -void GL2Encoder::restore2DTextureTarget() +void GL2Encoder::restore2DTextureTarget(GLenum target) { - GLenum priorityTarget = m_state->getPriorityEnabledTarget(GL_TEXTURE_2D); - m_glBindTexture_enc(this, GL_TEXTURE_2D, - m_state->getBoundTexture(priorityTarget)); + if (texture2DNeedsOverride(target)) { + m_glBindTexture_enc(this, GL_TEXTURE_2D, + m_state->getBoundTexture( + m_state->getPriorityEnabledTarget(GL_TEXTURE_2D))); + } } void GL2Encoder::s_glGenRenderbuffers(void* self, diff --git a/system/GLESv2_enc/GL2Encoder.h b/system/GLESv2_enc/GL2Encoder.h index 69bd4cf..a9ae723 100644 --- a/system/GLESv2_enc/GL2Encoder.h +++ b/system/GLESv2_enc/GL2Encoder.h @@ -44,7 +44,7 @@ public: virtual GLenum getError() { return m_error; }; void override2DTextureTarget(GLenum target); - void restore2DTextureTarget(); + void restore2DTextureTarget(GLenum target); private: @@ -65,6 +65,7 @@ private: void sendVertexAttributes(GLint first, GLsizei count); bool updateHostTexture2DBinding(GLenum texUnit, GLenum newTarget); + bool texture2DNeedsOverride(GLenum target) const; bool isCompleteFbo(const GLClientState* state, GLenum attachment) const; glGetError_client_proc_t m_glGetError_enc; -- 2.11.0