i965/gen6_surface_state.c: Remove (gen < 6) code path
[mesa.git] / src / mesa / drivers / common / meta.c
index 604bc218b7217fc4f9fe62db0f2a52bd30049521..485128696c5ae476f2ca7f4ce7a2c610210c5520 100644 (file)
@@ -40,6 +40,7 @@
 #include "main/blit.h"
 #include "main/bufferobj.h"
 #include "main/buffers.h"
+#include "main/clear.h"
 #include "main/colortab.h"
 #include "main/condrender.h"
 #include "main/depth.h"
@@ -47,6 +48,7 @@
 #include "main/fbobject.h"
 #include "main/feedback.h"
 #include "main/formats.h"
+#include "main/format_unpack.h"
 #include "main/glformats.h"
 #include "main/image.h"
 #include "main/macros.h"
@@ -71,6 +73,7 @@
 #include "main/teximage.h"
 #include "main/texparam.h"
 #include "main/texstate.h"
+#include "main/texstore.h"
 #include "main/transformfeedback.h"
 #include "main/uniforms.h"
 #include "main/varray.h"
@@ -81,7 +84,7 @@
 #include "drivers/common/meta.h"
 #include "main/enums.h"
 #include "main/glformats.h"
-#include "../glsl/ralloc.h"
+#include "util/ralloc.h"
 
 /** Return offset in bytes of the field within a vertex struct */
 #define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
@@ -98,18 +101,18 @@ static void meta_decompress_cleanup(struct decompress_state *decompress);
 static void meta_drawpix_cleanup(struct drawpix_state *drawpix);
 
 void
-_mesa_meta_bind_fbo_image(GLenum attachment,
+_mesa_meta_bind_fbo_image(GLenum fboTarget, GLenum attachment,
                           struct gl_texture_image *texImage, GLuint layer)
 {
    struct gl_texture_object *texObj = texImage->TexObject;
    int level = texImage->Level;
-   GLenum target = texObj->Target;
+   GLenum texTarget = texObj->Target;
 
-   switch (target) {
+   switch (texTarget) {
    case GL_TEXTURE_1D:
-      _mesa_FramebufferTexture1D(GL_FRAMEBUFFER,
+      _mesa_FramebufferTexture1D(fboTarget,
                                  attachment,
-                                 target,
+                                 texTarget,
                                  texObj->Name,
                                  level);
       break;
@@ -118,19 +121,19 @@ _mesa_meta_bind_fbo_image(GLenum attachment,
    case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
    case GL_TEXTURE_CUBE_MAP_ARRAY:
    case GL_TEXTURE_3D:
-      _mesa_FramebufferTextureLayer(GL_FRAMEBUFFER,
+      _mesa_FramebufferTextureLayer(fboTarget,
                                     attachment,
                                     texObj->Name,
                                     level,
                                     layer);
       break;
    default: /* 2D / cube */
-      if (target == GL_TEXTURE_CUBE_MAP)
-         target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
+      if (texTarget == GL_TEXTURE_CUBE_MAP)
+         texTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
 
-      _mesa_FramebufferTexture2D(GL_FRAMEBUFFER,
+      _mesa_FramebufferTexture2D(fboTarget,
                                  attachment,
-                                 target,
+                                 texTarget,
                                  texObj->Name,
                                  level);
    }
@@ -1524,12 +1527,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
 {
    const char *vs_source =
       "#extension GL_AMD_vertex_shader_layer : enable\n"
+      "#extension GL_ARB_draw_instanced : enable\n"
       "attribute vec4 position;\n"
-      "uniform int layer;\n"
       "void main()\n"
       "{\n"
       "#ifdef GL_AMD_vertex_shader_layer\n"
-      "   gl_Layer = layer;\n"
+      "   gl_Layer = gl_InstanceID;\n"
       "#endif\n"
       "   gl_Position = position;\n"
       "}\n";
@@ -1565,7 +1568,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
    _mesa_LinkProgram(clear->ShaderProg);
 
    clear->ColorLocation = _mesa_GetUniformLocation(clear->ShaderProg, "color");
-   clear->LayerLocation = _mesa_GetUniformLocation(clear->ShaderProg, "layer");
 
    has_integer_textures = _mesa_is_gles3(ctx) ||
       (_mesa_is_desktop_gl(ctx) && ctx->Const.GLSLVersion >= 130);
@@ -1576,12 +1578,12 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
          ralloc_asprintf(shader_source_mem_ctx,
                          "#version 130\n"
                          "#extension GL_AMD_vertex_shader_layer : enable\n"
+                         "#extension GL_ARB_draw_instanced : enable\n"
                          "in vec4 position;\n"
-                         "uniform int layer;\n"
                          "void main()\n"
                          "{\n"
                          "#ifdef GL_AMD_vertex_shader_layer\n"
-                         "   gl_Layer = layer;\n"
+                         "   gl_Layer = gl_InstanceID;\n"
                          "#endif\n"
                          "   gl_Position = position;\n"
                          "}\n");
@@ -1620,8 +1622,6 @@ meta_glsl_clear_init(struct gl_context *ctx, struct clear_state *clear)
 
       clear->IntegerColorLocation =
         _mesa_GetUniformLocation(clear->IntegerShaderProg, "color");
-      clear->IntegerLayerLocation =
-         _mesa_GetUniformLocation(clear->IntegerShaderProg, "layer");
    }
 }
 
@@ -1650,8 +1650,8 @@ meta_glsl_clear_cleanup(struct clear_state *clear)
  * Since the bitfield has no associated order, the assignment of draw buffer
  * indices to color attachment indices is rather arbitrary.
  */
-static void
-drawbuffers_from_bitfield(GLbitfield bits)
+void
+_mesa_meta_drawbuffers_from_bitfield(GLbitfield bits)
 {
    GLenum enums[MAX_DRAW_BUFFERS];
    int i = 0;
@@ -1764,7 +1764,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
    /* GL_COLOR_BUFFER_BIT */
    if (buffers & BUFFER_BITS_COLOR) {
       /* Only draw to the buffers we were asked to clear. */
-      drawbuffers_from_bitfield(buffers & BUFFER_BITS_COLOR);
+      _mesa_meta_drawbuffers_from_bitfield(buffers & BUFFER_BITS_COLOR);
 
       /* leave colormask state as-is */
 
@@ -1829,15 +1829,7 @@ meta_clear(struct gl_context *ctx, GLbitfield buffers, bool glsl)
 
    /* draw quad(s) */
    if (fb->MaxNumLayers > 0) {
-      unsigned layer;
-      assert(glsl && clear->LayerLocation != -1);
-      for (layer = 0; layer < fb->MaxNumLayers; layer++) {
-         if (fb->_IntegerColor)
-            _mesa_Uniform1i(clear->IntegerLayerLocation, layer);
-         else
-            _mesa_Uniform1i(clear->LayerLocation, layer);
-         _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-      }
+      _mesa_DrawArraysInstanced(GL_TRIANGLE_FAN, 0, 4, fb->MaxNumLayers);
    } else {
       _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
    }
@@ -2729,9 +2721,9 @@ _mesa_meta_blit_shader_table_cleanup(struct blit_shader_table *table)
 static GLenum
 get_temp_image_type(struct gl_context *ctx, mesa_format format)
 {
-   GLenum baseFormat;
-
-   baseFormat = _mesa_get_format_base_format(format);
+   const GLenum baseFormat = _mesa_get_format_base_format(format);
+   const GLenum datatype = _mesa_get_format_datatype(format);
+   const GLint format_red_bits = _mesa_get_format_bits(format, GL_RED_BITS);
 
    switch (baseFormat) {
    case GL_RGBA:
@@ -2742,30 +2734,24 @@ get_temp_image_type(struct gl_context *ctx, mesa_format format)
    case GL_LUMINANCE:
    case GL_LUMINANCE_ALPHA:
    case GL_INTENSITY:
-      if (ctx->DrawBuffer->Visual.redBits <= 8) {
+      if (datatype == GL_INT || datatype == GL_UNSIGNED_INT) {
+         return datatype;
+      } else if (format_red_bits <= 8) {
          return GL_UNSIGNED_BYTE;
-      } else if (ctx->DrawBuffer->Visual.redBits <= 16) {
+      } else if (format_red_bits <= 16) {
          return GL_UNSIGNED_SHORT;
-      } else {
-         GLenum datatype = _mesa_get_format_datatype(format);
-         if (datatype == GL_INT || datatype == GL_UNSIGNED_INT)
-            return datatype;
-         return GL_FLOAT;
       }
-   case GL_DEPTH_COMPONENT: {
-      GLenum datatype = _mesa_get_format_datatype(format);
+      return GL_FLOAT;
+   case GL_DEPTH_COMPONENT:
       if (datatype == GL_FLOAT)
          return GL_FLOAT;
       else
          return GL_UNSIGNED_INT;
-   }
-   case GL_DEPTH_STENCIL: {
-      GLenum datatype = _mesa_get_format_datatype(format);
+   case GL_DEPTH_STENCIL:
       if (datatype == GL_FLOAT)
          return GL_FLOAT_32_UNSIGNED_INT_24_8_REV;
       else
          return GL_UNSIGNED_INT_24_8;
-   }
    default:
       _mesa_problem(ctx, "Unexpected format %d in get_temp_image_type()",
                    baseFormat);
@@ -2805,17 +2791,20 @@ copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, GLuint dims,
 
    if (rb->_BaseFormat == GL_DEPTH_STENCIL ||
        rb->_BaseFormat == GL_DEPTH_COMPONENT) {
-      _mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset);
+      _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                texImage, zoffset);
       mask = GL_DEPTH_BUFFER_BIT;
 
       if (rb->_BaseFormat == GL_DEPTH_STENCIL &&
           texImage->_BaseFormat == GL_DEPTH_STENCIL) {
-         _mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset);
+         _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                   texImage, zoffset);
          mask |= GL_STENCIL_BUFFER_BIT;
       }
       _mesa_DrawBuffer(GL_NONE);
    } else {
-      _mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset);
+      _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                                texImage, zoffset);
       mask = GL_COLOR_BUFFER_BIT;
       _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);
    }
@@ -2943,14 +2932,22 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
    free(buf);
 }
 
+static void
+meta_decompress_fbo_cleanup(struct decompress_fbo_state *decompress_fbo)
+{
+   if (decompress_fbo->FBO != 0) {
+      _mesa_DeleteFramebuffers(1, &decompress_fbo->FBO);
+      _mesa_DeleteRenderbuffers(1, &decompress_fbo->RBO);
+   }
+
+   memset(decompress_fbo, 0, sizeof(*decompress_fbo));
+}
 
 static void
 meta_decompress_cleanup(struct decompress_state *decompress)
 {
-   if (decompress->FBO != 0) {
-      _mesa_DeleteFramebuffers(1, &decompress->FBO);
-      _mesa_DeleteRenderbuffers(1, &decompress->RBO);
-   }
+   meta_decompress_fbo_cleanup(&decompress->byteFBO);
+   meta_decompress_fbo_cleanup(&decompress->floatFBO);
 
    if (decompress->VAO != 0) {
       _mesa_DeleteVertexArrays(1, &decompress->VAO);
@@ -2972,7 +2969,7 @@ meta_decompress_cleanup(struct decompress_state *decompress)
  * \param dest  destination buffer
  * \param destRowLength  dest image rowLength (ala GL_PACK_ROW_LENGTH)
  */
-static void
+static bool
 decompress_texture_image(struct gl_context *ctx,
                          struct gl_texture_image *texImage,
                          GLuint slice,
@@ -2980,17 +2977,33 @@ decompress_texture_image(struct gl_context *ctx,
                          GLvoid *dest)
 {
    struct decompress_state *decompress = &ctx->Meta->Decompress;
+   struct decompress_fbo_state *decompress_fbo;
    struct gl_texture_object *texObj = texImage->TexObject;
    const GLint width = texImage->Width;
    const GLint height = texImage->Height;
    const GLint depth = texImage->Height;
    const GLenum target = texObj->Target;
+   GLenum rbFormat;
    GLenum faceTarget;
    struct vertex verts[4];
    GLuint samplerSave;
+   GLenum status;
    const bool use_glsl_version = ctx->Extensions.ARB_vertex_shader &&
                                       ctx->Extensions.ARB_fragment_shader;
 
+   switch (_mesa_get_format_datatype(texImage->TexFormat)) {
+   case GL_FLOAT:
+      decompress_fbo = &decompress->floatFBO;
+      rbFormat = GL_RGBA32F;
+      break;
+   case GL_UNSIGNED_NORMALIZED:
+      decompress_fbo = &decompress->byteFBO;
+      rbFormat = GL_RGBA;
+      break;
+   default:
+      return false;
+   }
+
    if (slice > 0) {
       assert(target == GL_TEXTURE_3D ||
              target == GL_TEXTURE_2D_ARRAY ||
@@ -3001,11 +3014,11 @@ decompress_texture_image(struct gl_context *ctx,
    case GL_TEXTURE_1D:
    case GL_TEXTURE_1D_ARRAY:
       assert(!"No compressed 1D textures.");
-      return;
+      return false;
 
    case GL_TEXTURE_3D:
       assert(!"No compressed 3D textures.");
-      return;
+      return false;
 
    case GL_TEXTURE_CUBE_MAP_ARRAY:
       faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + (slice % 6);
@@ -3027,27 +3040,35 @@ decompress_texture_image(struct gl_context *ctx,
          ctx->Texture.Unit[ctx->Texture.CurrentUnit].Sampler->Name : 0;
 
    /* Create/bind FBO/renderbuffer */
-   if (decompress->FBO == 0) {
-      _mesa_GenFramebuffers(1, &decompress->FBO);
-      _mesa_GenRenderbuffers(1, &decompress->RBO);
-      _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO);
-      _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO);
+   if (decompress_fbo->FBO == 0) {
+      _mesa_GenFramebuffers(1, &decompress_fbo->FBO);
+      _mesa_GenRenderbuffers(1, &decompress_fbo->RBO);
+      _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress_fbo->FBO);
+      _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress_fbo->RBO);
       _mesa_FramebufferRenderbuffer(GL_FRAMEBUFFER_EXT,
                                        GL_COLOR_ATTACHMENT0_EXT,
                                        GL_RENDERBUFFER_EXT,
-                                       decompress->RBO);
+                                       decompress_fbo->RBO);
    }
    else {
-      _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress->FBO);
+      _mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, decompress_fbo->FBO);
    }
 
    /* alloc dest surface */
-   if (width > decompress->Width || height > decompress->Height) {
-      _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress->RBO);
-      _mesa_RenderbufferStorage(GL_RENDERBUFFER_EXT, GL_RGBA,
-                                   width, height);
-      decompress->Width = width;
-      decompress->Height = height;
+   if (width > decompress_fbo->Width || height > decompress_fbo->Height) {
+      _mesa_BindRenderbuffer(GL_RENDERBUFFER_EXT, decompress_fbo->RBO);
+      _mesa_RenderbufferStorage(GL_RENDERBUFFER_EXT, rbFormat,
+                                width, height);
+      status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+      if (status != GL_FRAMEBUFFER_COMPLETE) {
+         /* If the framebuffer isn't complete then we'll leave
+          * decompress_fbo->Width as zero so that it will fail again next time
+          * too */
+         _mesa_meta_end(ctx);
+         return false;
+      }
+      decompress_fbo->Width = width;
+      decompress_fbo->Height = height;
    }
 
    if (use_glsl_version) {
@@ -3169,6 +3190,8 @@ decompress_texture_image(struct gl_context *ctx,
    _mesa_BindSampler(ctx->Texture.CurrentUnit, samplerSave);
 
    _mesa_meta_end(ctx);
+
+   return true;
 }
 
 
@@ -3182,15 +3205,11 @@ _mesa_meta_GetTexImage(struct gl_context *ctx,
                        GLenum format, GLenum type, GLvoid *pixels,
                        struct gl_texture_image *texImage)
 {
-   /* We can only use the decompress-with-blit method here if the texels are
-    * unsigned, normalized values.  We could handle signed and unnormalized 
-    * with floating point renderbuffers...
-    */
-   if (_mesa_is_format_compressed(texImage->TexFormat) &&
-       _mesa_get_format_datatype(texImage->TexFormat)
-       == GL_UNSIGNED_NORMALIZED) {
+   if (_mesa_is_format_compressed(texImage->TexFormat)) {
       struct gl_texture_object *texObj = texImage->TexObject;
       GLuint slice;
+      bool result;
+
       /* Need to unlock the texture here to prevent deadlock... */
       _mesa_unlock_texture(ctx, texObj);
       for (slice = 0; slice < texImage->Depth; slice++) {
@@ -3212,14 +3231,19 @@ _mesa_meta_GetTexImage(struct gl_context *ctx,
          else {
             dst = pixels;
          }
-         decompress_texture_image(ctx, texImage, slice, format, type, dst);
+         result = decompress_texture_image(ctx, texImage, slice,
+                                           format, type, dst);
+         if (!result)
+            break;
       }
       /* ... and relock it */
       _mesa_lock_texture(ctx, texObj);
+
+      if (result)
+         return;
    }
-   else {
-      _mesa_get_teximage(ctx, format, type, pixels, texImage);
-   }
+
+   _mesa_get_teximage(ctx, format, type, pixels, texImage);
 }
 
 
@@ -3347,3 +3371,192 @@ _mesa_meta_DrawTex(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z,
 
    _mesa_meta_end(ctx);
 }
+
+static bool
+cleartexsubimage_color(struct gl_context *ctx,
+                       struct gl_texture_image *texImage,
+                       const GLvoid *clearValue,
+                       GLint zoffset)
+{
+   mesa_format format;
+   union gl_color_union colorValue;
+   GLenum datatype;
+   GLenum status;
+
+   _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+                             texImage, zoffset);
+
+   status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+   if (status != GL_FRAMEBUFFER_COMPLETE)
+      return false;
+
+   /* We don't want to apply an sRGB conversion so override the format */
+   format = _mesa_get_srgb_format_linear(texImage->TexFormat);
+   datatype = _mesa_get_format_datatype(format);
+
+   switch (datatype) {
+   case GL_UNSIGNED_INT:
+   case GL_INT:
+      if (clearValue)
+         _mesa_unpack_uint_rgba_row(format, 1, clearValue,
+                                    (GLuint (*)[4]) colorValue.ui);
+      else
+         memset(&colorValue, 0, sizeof colorValue);
+      if (datatype == GL_INT)
+         _mesa_ClearBufferiv(GL_COLOR, 0, colorValue.i);
+      else
+         _mesa_ClearBufferuiv(GL_COLOR, 0, colorValue.ui);
+      break;
+   default:
+      if (clearValue)
+         _mesa_unpack_rgba_row(format, 1, clearValue,
+                               (GLfloat (*)[4]) colorValue.f);
+      else
+         memset(&colorValue, 0, sizeof colorValue);
+      _mesa_ClearBufferfv(GL_COLOR, 0, colorValue.f);
+      break;
+   }
+
+   return true;
+}
+
+static bool
+cleartexsubimage_depth_stencil(struct gl_context *ctx,
+                               struct gl_texture_image *texImage,
+                               const GLvoid *clearValue,
+                               GLint zoffset)
+{
+   GLint stencilValue;
+   GLfloat depthValue;
+   GLenum status;
+
+   _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                             texImage, zoffset);
+
+   if (texImage->_BaseFormat == GL_DEPTH_STENCIL)
+      _mesa_meta_bind_fbo_image(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
+                                texImage, zoffset);
+
+   status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
+   if (status != GL_FRAMEBUFFER_COMPLETE)
+      return false;
+
+   if (clearValue) {
+      GLuint depthStencilValue[2];
+
+      /* Convert the clearValue from whatever format it's in to a floating
+       * point value for the depth and an integer value for the stencil index
+       */
+      _mesa_unpack_float_32_uint_24_8_depth_stencil_row(texImage->TexFormat,
+                                                        1, /* n */
+                                                        clearValue,
+                                                        depthStencilValue);
+      /* We need a memcpy here instead of a cast because we need to
+       * reinterpret the bytes as a float rather than converting it
+       */
+      memcpy(&depthValue, depthStencilValue, sizeof depthValue);
+      stencilValue = depthStencilValue[1] & 0xff;
+   } else {
+      depthValue = 0.0f;
+      stencilValue = 0;
+   }
+
+   if (texImage->_BaseFormat == GL_DEPTH_STENCIL)
+      _mesa_ClearBufferfi(GL_DEPTH_STENCIL, 0, depthValue, stencilValue);
+   else
+      _mesa_ClearBufferfv(GL_DEPTH, 0, &depthValue);
+
+   return true;
+}
+
+static bool
+cleartexsubimage_for_zoffset(struct gl_context *ctx,
+                             struct gl_texture_image *texImage,
+                             GLint zoffset,
+                             const GLvoid *clearValue)
+{
+   GLuint fbo;
+   bool success;
+
+   _mesa_GenFramebuffers(1, &fbo);
+   _mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
+
+   switch(texImage->_BaseFormat) {
+   case GL_DEPTH_STENCIL:
+   case GL_DEPTH_COMPONENT:
+      success = cleartexsubimage_depth_stencil(ctx, texImage,
+                                               clearValue, zoffset);
+      break;
+   default:
+      success = cleartexsubimage_color(ctx, texImage, clearValue, zoffset);
+      break;
+   }
+
+   _mesa_DeleteFramebuffers(1, &fbo);
+
+   return success;
+}
+
+static bool
+cleartexsubimage_using_fbo(struct gl_context *ctx,
+                           struct gl_texture_image *texImage,
+                           GLint xoffset, GLint yoffset, GLint zoffset,
+                           GLsizei width, GLsizei height, GLsizei depth,
+                           const GLvoid *clearValue)
+{
+   bool success = true;
+   GLint z;
+
+   _mesa_meta_begin(ctx,
+                    MESA_META_SCISSOR |
+                    MESA_META_COLOR_MASK |
+                    MESA_META_DITHER |
+                    MESA_META_FRAMEBUFFER_SRGB);
+
+   _mesa_set_enable(ctx, GL_DITHER, GL_FALSE);
+
+   _mesa_set_enable(ctx, GL_SCISSOR_TEST, GL_TRUE);
+   _mesa_Scissor(xoffset, yoffset, width, height);
+
+   for (z = zoffset; z < zoffset + depth; z++) {
+      if (!cleartexsubimage_for_zoffset(ctx, texImage, z, clearValue)) {
+         success = false;
+         break;
+      }
+   }
+
+   _mesa_meta_end(ctx);
+
+   return success;
+}
+
+extern void
+_mesa_meta_ClearTexSubImage(struct gl_context *ctx,
+                            struct gl_texture_image *texImage,
+                            GLint xoffset, GLint yoffset, GLint zoffset,
+                            GLsizei width, GLsizei height, GLsizei depth,
+                            const GLvoid *clearValue)
+{
+   bool res;
+
+   _mesa_unlock_texture(ctx, texImage->TexObject);
+
+   res = cleartexsubimage_using_fbo(ctx, texImage,
+                                    xoffset, yoffset, zoffset,
+                                    width, height, depth,
+                                    clearValue);
+
+   _mesa_lock_texture(ctx, texImage->TexObject);
+
+   if (res)
+      return;
+
+   _mesa_warning(ctx,
+                 "Falling back to mapping the texture in "
+                 "glClearTexSubImage\n");
+
+   _mesa_store_cleartexsubimage(ctx, texImage,
+                                xoffset, yoffset, zoffset,
+                                width, height, depth,
+                                clearValue);
+}