[AMD] Fix segfault in glCopyTexImage + cube map luminance

bug: 31523568

In particular, the test

dEQP.functional.texture.specification.basic_copyteximage2d.cube_luminance

segfaults the emulator on some AMD GPUs.

When we define cube maps using glCopyTexImage2D
and are using the GL_LUMINANCE internal format, if the negative
components of the cube map are defined first, the host AMD driver may
segfault (tested in Mobility Radeon and RX 480).

The workaround is to detect this particular API call, cube map target,
and internal format, and define the positive component first
using the same arguments, if the positive component has not been defined
already.

Change-Id: I26ed25bf3b7358ed7121a52f89d541c325beb6e4
diff --git a/system/GLESv2_enc/GL2Encoder.cpp b/system/GLESv2_enc/GL2Encoder.cpp
index a32fcdb..43b8e34 100755
--- a/system/GLESv2_enc/GL2Encoder.cpp
+++ b/system/GLESv2_enc/GL2Encoder.cpp
@@ -134,6 +134,7 @@
     OVERRIDE(glTexParameteriv);
     OVERRIDE(glTexImage2D);
     OVERRIDE(glTexSubImage2D);
+    OVERRIDE(glCopyTexImage2D);
 
     OVERRIDE(glGenRenderbuffers);
     OVERRIDE(glDeleteRenderbuffers);
@@ -1455,6 +1456,30 @@
     }
 }
 
+void GL2Encoder::s_glCopyTexImage2D(void* self, GLenum target, GLint level,
+        GLenum internalformat, GLint x, GLint y,
+        GLsizei width, GLsizei height, GLint border)
+{
+    GL2Encoder* ctx = (GL2Encoder*)self;
+    GLClientState* state = ctx->m_state;
+
+    // This is needed to work around underlying OpenGL drivers
+    // (such as those feeding some some AMD GPUs) that expect
+    // positive components of cube maps to be defined _before_
+    // the negative components (otherwise a segfault occurs).
+    GLenum extraTarget =
+        state->copyTexImageLuminanceCubeMapAMDWorkaround
+            (target, level, internalformat);
+
+    if (extraTarget) {
+        ctx->m_glCopyTexImage2D_enc(ctx, extraTarget, level, internalformat,
+                                    x, y, width, height, border);
+    }
+
+    ctx->m_glCopyTexImage2D_enc(ctx, target, level, internalformat,
+                                x, y, width, height, border);
+}
+
 void GL2Encoder::s_glTexParameteriv(void* self,
         GLenum target, GLenum pname, const GLint* params)
 {