OSDN Git Service

[CTS][deqp] avoid rebinding textures in glTex(Sub)Image2D
authorLingfeng Yang <lfy@google.com>
Wed, 7 Sep 2016 21:40:03 +0000 (14:40 -0700)
committerLingfeng Yang <lfy@google.com>
Thu, 8 Sep 2016 19:34:55 +0000 (12:34 -0700)
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
system/GLESv2_enc/GL2Encoder.cpp
system/GLESv2_enc/GL2Encoder.h

index 5aaac5f..ec82046 100644 (file)
@@ -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<GLeglImageOES>((intptr_t)image->host_egl_image);
         ctx->m_glEGLImageTargetTexture2DOES_enc(self, target, hostImage);
-        ctx->restore2DTextureTarget();
+        ctx->restore2DTextureTarget(target);
     }
 }
 
index 97557c9..a32fcdb 100755 (executable)
@@ -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,
index 69bd4cf..a9ae723 100644 (file)
@@ -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;