[Mesa-dev] [PATCH V4 02/19] mesa: add texobj support for ARB_texture_multisample

Chris Forbes chrisf at ijw.co.nz
Tue Feb 26 02:10:43 PST 2013


Adds the new texture targets, and per-image state for GL_TEXTURE_SAMPLES
and GL_TEXTURE_FIXED_SAMPLE_LOCATIONS.

V2: - Allow multisample texture targets in glInvalidateTexSubImage too.
      This was already partly there, but I missed it the first time around
      since the interaction is defined in a newer extension. Fixed weird
      indentation.
    - Allow multisample array textures in glFramebufferTextureLayer.
      This was overlooked as the tests originally only used 2d
      multisample textures.

V3: - Set min/mag filters sensibly for multisample textures. This
      can't actually be changed by the user, so it's more sensible to
      initialize it correctly than to hack around it being bogus later.

V4: - Tidy up initial min/mag filter setup. Setup in
      _mesa_initialize_texture_object was bogus, but benign since
      finish_texture_init() clobbered everything with correct values. For V4,
      just do the setup in finish_texture_init().

Signed-off-by: Chris Forbes <chrisf at ijw.co.nz>
[V2] Reviewed-by: Paul Berry <stereotype441 at gmail.com>
[V4] Reviewed-by: Eric Anholt <eric at anholt.net>
---
 src/mesa/main/fbobject.c         | 11 ++++--
 src/mesa/main/get.c              |  3 ++
 src/mesa/main/get_hash_params.py |  5 +++
 src/mesa/main/mtypes.h           |  8 +++++
 src/mesa/main/shared.c           |  2 ++
 src/mesa/main/teximage.c         | 60 ++++++++++++++++++++++++++++++--
 src/mesa/main/texobj.c           | 75 ++++++++++++++++++++++++++++++----------
 src/mesa/main/texparam.c         | 16 +++++++++
 src/mesa/main/texstate.c         |  2 ++
 9 files changed, 160 insertions(+), 22 deletions(-)

diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 89bc575..3cd242e 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -2069,7 +2069,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
             err = (texObj->Target != GL_TEXTURE_3D) &&
                 (texObj->Target != GL_TEXTURE_1D_ARRAY_EXT) &&
                 (texObj->Target != GL_TEXTURE_2D_ARRAY_EXT) &&
-                (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY);
+                (texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY) &&
+                (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
          }
          else {
             /* Make sure textarget is consistent with the texture's type */
@@ -2103,7 +2104,8 @@ framebuffer_texture(struct gl_context *ctx, const char *caller, GLenum target,
       }
       else if ((texObj->Target == GL_TEXTURE_1D_ARRAY_EXT) ||
                (texObj->Target == GL_TEXTURE_2D_ARRAY_EXT) ||
-               (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY)) {
+               (texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY) ||
+               (texObj->Target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY)) {
          if (zoffset < 0 ||
              zoffset >= (GLint) ctx->Const.MaxArrayTextureLayers) {
             _mesa_error(ctx, GL_INVALID_VALUE,
@@ -2255,6 +2257,11 @@ _mesa_FramebufferTexture2D(GLenum target, GLenum attachment,
          error = (_mesa_is_gles(ctx) && ctx->Version < 30)
             || !ctx->Extensions.EXT_texture_array;
          break;
+      case GL_TEXTURE_2D_MULTISAMPLE:
+      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+         error = _mesa_is_gles(ctx)
+            || !ctx->Extensions.ARB_texture_multisample;
+         break;
       default:
          error = GL_TRUE;
       }
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index da1e01c..056bacb 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -354,6 +354,7 @@ EXTRA_EXT(ARB_timer_query);
 EXTRA_EXT(ARB_map_buffer_alignment);
 EXTRA_EXT(ARB_texture_cube_map_array);
 EXTRA_EXT(ARB_texture_buffer_range);
+EXTRA_EXT(ARB_texture_multisample);
 
 static const int
 extra_NV_primitive_restart[] = {
@@ -693,6 +694,8 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu
    case GL_TEXTURE_BINDING_RECTANGLE_NV:
    case GL_TEXTURE_BINDING_EXTERNAL_OES:
    case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
+   case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
       unit = ctx->Texture.CurrentUnit;
       v->value_int =
 	 ctx->Texture.Unit[unit].CurrentTex[d->offset]->Name;
diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py
index 1b7d6ad..205139d 100644
--- a/src/mesa/main/get_hash_params.py
+++ b/src/mesa/main/get_hash_params.py
@@ -658,6 +658,11 @@ descriptor=[
   [ "TEXTURE_BUFFER_FORMAT_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
   [ "TEXTURE_BUFFER_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ],
 
+# GL_ARB_texture_multisample / GL 3.2
+  [ "TEXTURE_BINDING_2D_MULTISAMPLE", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_INDEX, extra_ARB_texture_multisample" ],
+  [ "TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX, extra_ARB_texture_multisample" ],
+
+
 # GL_ARB_sampler_objects / GL 3.3
   [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ],
 
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index b92f98e..a292d98 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1148,6 +1148,8 @@ struct gl_stencil_attrib
  */
 typedef enum
 {
+   TEXTURE_2D_MULTISAMPLE_INDEX,
+   TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX,
    TEXTURE_CUBE_ARRAY_INDEX,
    TEXTURE_BUFFER_INDEX,
    TEXTURE_2D_ARRAY_INDEX,
@@ -1167,6 +1169,8 @@ typedef enum
  * Used for Texture.Unit[]._ReallyEnabled flags.
  */
 /*@{*/
+#define TEXTURE_2D_MULTISAMPLE_BIT (1 << TEXTURE_2D_MULTISAMPLE_INDEX)
+#define TEXTURE_2D_MULTISAMPLE_ARRAY_BIT (1 << TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX)
 #define TEXTURE_CUBE_ARRAY_BIT (1 << TEXTURE_CUBE_ARRAY_INDEX)
 #define TEXTURE_BUFFER_BIT   (1 << TEXTURE_BUFFER_INDEX)
 #define TEXTURE_2D_ARRAY_BIT (1 << TEXTURE_2D_ARRAY_INDEX)
@@ -1212,6 +1216,10 @@ struct gl_texture_image
    GLuint Level;                /**< Which mipmap level am I? */
    /** Cube map face: index into gl_texture_object::Image[] array */
    GLuint Face;
+
+   /** GL_ARB_texture_multisample */
+   GLuint NumSamples;               /**< Sample count, or 0 for non-multisample */
+   GLboolean FixedSampleLocations;  /**< Same sample locations for all pixels? */
 };
 
 
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index a98a45c..4081259 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -92,6 +92,8 @@ _mesa_alloc_shared_state(struct gl_context *ctx)
    for (i = 0; i < NUM_TEXTURE_TARGETS; i++) {
       /* NOTE: the order of these enums matches the TEXTURE_x_INDEX values */
       static const GLenum targets[] = {
+         GL_TEXTURE_2D_MULTISAMPLE,
+         GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
          GL_TEXTURE_CUBE_MAP_ARRAY,
          GL_TEXTURE_BUFFER,
          GL_TEXTURE_2D_ARRAY_EXT,
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index d40d58e..9209d86 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -661,7 +661,7 @@ _mesa_is_proxy_texture(GLenum target)
     * NUM_TEXTURE_TARGETS should match number of terms below, except there's no
     * proxy for GL_TEXTURE_BUFFER and GL_TEXTURE_EXTERNAL_OES.
     */
-   assert(NUM_TEXTURE_TARGETS == 8 + 2);
+   assert(NUM_TEXTURE_TARGETS == 10 + 2);
 
    return (target == GL_PROXY_TEXTURE_1D ||
            target == GL_PROXY_TEXTURE_2D ||
@@ -670,7 +670,9 @@ _mesa_is_proxy_texture(GLenum target)
            target == GL_PROXY_TEXTURE_RECTANGLE_NV ||
            target == GL_PROXY_TEXTURE_1D_ARRAY_EXT ||
            target == GL_PROXY_TEXTURE_2D_ARRAY_EXT ||
-           target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY);
+           target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY ||
+           target == GL_PROXY_TEXTURE_2D_MULTISAMPLE ||
+           target == GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY);
 }
 
 
@@ -711,6 +713,12 @@ _mesa_get_proxy_target(GLenum target)
    case GL_TEXTURE_CUBE_MAP_ARRAY:
    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
       return GL_PROXY_TEXTURE_CUBE_MAP_ARRAY;
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+      return GL_PROXY_TEXTURE_2D_MULTISAMPLE;
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY;
    default:
       _mesa_problem(NULL, "unexpected target in _mesa_get_proxy_target()");
       return 0;
@@ -788,6 +796,18 @@ _mesa_select_tex_object(struct gl_context *ctx,
       case GL_TEXTURE_EXTERNAL_OES:
          return ctx->Extensions.OES_EGL_image_external
             ? texUnit->CurrentTex[TEXTURE_EXTERNAL_INDEX] : NULL;
+      case GL_TEXTURE_2D_MULTISAMPLE:
+         return ctx->Extensions.ARB_texture_multisample
+            ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+      case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+         return ctx->Extensions.ARB_texture_multisample
+            ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_INDEX] : NULL;
+      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+         return ctx->Extensions.ARB_texture_multisample
+            ? texUnit->CurrentTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
+      case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+         return ctx->Extensions.ARB_texture_multisample
+            ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL;
       default:
          _mesa_problem(NULL, "bad target in _mesa_select_tex_object()");
          return NULL;
@@ -918,6 +938,16 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level)
          return NULL;
       texIndex = TEXTURE_CUBE_ARRAY_INDEX;
       break;
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+      if (level > 0)
+         return 0;
+      texIndex = TEXTURE_2D_MULTISAMPLE_INDEX;
+      break;
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      if (level > 0)
+         return 0;
+      texIndex = TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX;
+      break;
    default:
       return NULL;
    }
@@ -987,6 +1017,13 @@ _mesa_max_texture_levels(struct gl_context *ctx, GLenum target)
    case GL_TEXTURE_BUFFER:
       return ctx->API == API_OPENGL_CORE &&
              ctx->Extensions.ARB_texture_buffer_object ? 1 : 0;
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return _mesa_is_desktop_gl(ctx)
+         && ctx->Extensions.ARB_texture_multisample
+         ? 1 : 0;
    case GL_TEXTURE_EXTERNAL_OES:
       /* fall-through */
    default:
@@ -1020,6 +1057,8 @@ _mesa_get_texture_dimensions(GLenum target)
    case GL_TEXTURE_1D_ARRAY:
    case GL_PROXY_TEXTURE_1D_ARRAY:
    case GL_TEXTURE_EXTERNAL_OES:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
       return 2;
    case GL_TEXTURE_3D:
    case GL_PROXY_TEXTURE_3D:
@@ -1027,6 +1066,8 @@ _mesa_get_texture_dimensions(GLenum target)
    case GL_PROXY_TEXTURE_2D_ARRAY:
    case GL_TEXTURE_CUBE_MAP_ARRAY:
    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
       return 3;
    case GL_TEXTURE_BUFFER:
       /* fall-through */
@@ -1068,6 +1109,8 @@ _mesa_get_tex_max_num_levels(GLenum target, GLsizei width, GLsizei height,
       break;
    case GL_TEXTURE_RECTANGLE:
    case GL_TEXTURE_EXTERNAL_OES:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
       return 1;
    default:
       assert(0);
@@ -1153,6 +1196,8 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->HeightLog2 = 0;
    img->DepthLog2 = 0;
    img->TexFormat = MESA_FORMAT_NONE;
+   img->NumSamples = 0;
+   img->FixedSampleLocations = GL_TRUE;
 }
 
 
@@ -1196,6 +1241,9 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
    img->Width2 = width - 2 * border;   /* == 1 << img->WidthLog2; */
    img->WidthLog2 = _mesa_logbase2(img->Width2);
 
+   img->NumSamples = 0;
+   img->FixedSampleLocations = GL_TRUE;
+
    switch(target) {
    case GL_TEXTURE_1D:
    case GL_TEXTURE_BUFFER:
@@ -1234,6 +1282,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
    case GL_PROXY_TEXTURE_2D:
    case GL_PROXY_TEXTURE_RECTANGLE:
    case GL_PROXY_TEXTURE_CUBE_MAP:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
       img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
       img->HeightLog2 = _mesa_logbase2(img->Height2);
       if (depth == 0)
@@ -1246,6 +1296,8 @@ _mesa_init_teximage_fields(struct gl_context *ctx,
    case GL_PROXY_TEXTURE_2D_ARRAY:
    case GL_TEXTURE_CUBE_MAP_ARRAY:
    case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
       img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */
       img->HeightLog2 = _mesa_logbase2(img->Height2);
       img->Depth2 = depth; /* no border */
@@ -1317,6 +1369,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
 
    case GL_TEXTURE_2D:
    case GL_PROXY_TEXTURE_2D:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       maxSize >>= level;
       if (width < 2 * border || width > 2 * border + maxSize)
@@ -1399,6 +1453,8 @@ _mesa_legal_texture_dimensions(struct gl_context *ctx, GLenum target,
 
    case GL_TEXTURE_2D_ARRAY_EXT:
    case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
       maxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
       maxSize >>= level;
       if (width < 2 * border || width > 2 * border + maxSize)
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index e99b0dc..d4be097 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -109,7 +109,9 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj,
           target == GL_TEXTURE_2D_ARRAY_EXT ||
           target == GL_TEXTURE_EXTERNAL_OES ||
           target == GL_TEXTURE_CUBE_MAP_ARRAY ||
-          target == GL_TEXTURE_BUFFER);
+          target == GL_TEXTURE_BUFFER ||
+          target == GL_TEXTURE_2D_MULTISAMPLE ||
+          target == GL_TEXTURE_2D_MULTISAMPLE_ARRAY);
 
    memset(obj, 0, sizeof(*obj));
    /* init the non-zero fields */
@@ -166,23 +168,39 @@ static void
 finish_texture_init(struct gl_context *ctx, GLenum target,
                     struct gl_texture_object *obj)
 {
+   GLenum filter = GL_LINEAR;
    assert(obj->Target == 0);
 
-   if (target == GL_TEXTURE_RECTANGLE_NV ||
-       target == GL_TEXTURE_EXTERNAL_OES) {
-      /* have to init wrap and filter state here - kind of klunky */
-      obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
-      obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
-      obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
-      obj->Sampler.MinFilter = GL_LINEAR;
-      if (ctx->Driver.TexParameter) {
-         static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
-         static const GLfloat fparam_filter[1] = {(GLfloat) GL_LINEAR};
-         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
-         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
-         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
-         ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_MIN_FILTER, fparam_filter);
-      }
+   switch (target) {
+      case GL_TEXTURE_2D_MULTISAMPLE:
+      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+         filter = GL_NEAREST;
+         /* fallthrough */
+
+      case GL_TEXTURE_RECTANGLE_NV:
+      case GL_TEXTURE_EXTERNAL_OES:
+         /* have to init wrap and filter state here - kind of klunky */
+         obj->Sampler.WrapS = GL_CLAMP_TO_EDGE;
+         obj->Sampler.WrapT = GL_CLAMP_TO_EDGE;
+         obj->Sampler.WrapR = GL_CLAMP_TO_EDGE;
+         obj->Sampler.MinFilter = filter;
+         obj->Sampler.MagFilter = filter;
+         if (ctx->Driver.TexParameter) {
+            static const GLfloat fparam_wrap[1] = {(GLfloat) GL_CLAMP_TO_EDGE};
+            const GLfloat fparam_filter[1] = {(GLfloat) filter};
+            ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_S, fparam_wrap);
+            ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_T, fparam_wrap);
+            ctx->Driver.TexParameter(ctx, target, obj, GL_TEXTURE_WRAP_R, fparam_wrap);
+            ctx->Driver.TexParameter(ctx, target, obj,
+                  GL_TEXTURE_MIN_FILTER, fparam_filter);
+            ctx->Driver.TexParameter(ctx, target, obj,
+                  GL_TEXTURE_MAG_FILTER, fparam_filter);
+         }
+         break;
+
+      default:
+         /* nothing needs done */
+         break;
    }
 }
 
@@ -318,6 +336,8 @@ valid_texture_object(const struct gl_texture_object *tex)
    case GL_TEXTURE_BUFFER:
    case GL_TEXTURE_EXTERNAL_OES:
    case GL_TEXTURE_CUBE_MAP_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
       return GL_TRUE;
    case 0x99:
       _mesa_problem(NULL, "invalid reference to a deleted texture object");
@@ -517,6 +537,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
    case GL_TEXTURE_RECTANGLE_NV:
    case GL_TEXTURE_BUFFER:
    case GL_TEXTURE_EXTERNAL_OES:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
       maxLevels = 1;  /* no mipmapping */
       break;
    default:
@@ -585,7 +607,9 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx,
       height = baseImage->Height2;
       depth = baseImage->Depth2;
 
-      /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL textures */
+      /* Note: this loop will be a no-op for RECT, BUFFER, EXTERNAL,
+       * MULTISAMPLE and MULTISAMPLE_ARRAY textures
+       */
       for (i = baseLevel + 1; i < maxLevels; i++) {
          /* Compute the expected size of image at level[i] */
          if (width > 1) {
@@ -763,7 +787,7 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
          dims = 0;
          target = GL_TEXTURE_BUFFER;
          break;
-     case TEXTURE_CUBE_ARRAY_INDEX:
+      case TEXTURE_CUBE_ARRAY_INDEX:
          dims = 3;
          target = GL_TEXTURE_CUBE_MAP_ARRAY;
          break;
@@ -771,6 +795,14 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex)
          dims = 2;
          target = GL_TEXTURE_EXTERNAL_OES;
          break;
+      case TEXTURE_2D_MULTISAMPLE_INDEX:
+         dims = 2;
+         target = GL_TEXTURE_2D_MULTISAMPLE;
+         break;
+      case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX:
+         dims = 3;
+         target = GL_TEXTURE_2D_MULTISAMPLE_ARRAY;
+         break;
       default:
          /* no-op */
          return NULL;
@@ -1156,6 +1188,12 @@ target_enum_to_index(struct gl_context *ctx, GLenum target)
          ? TEXTURE_EXTERNAL_INDEX : -1;
    case GL_TEXTURE_CUBE_MAP_ARRAY:
       return TEXTURE_CUBE_ARRAY_INDEX;
+   case GL_TEXTURE_2D_MULTISAMPLE:
+      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+         ? TEXTURE_2D_MULTISAMPLE_INDEX: -1;
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_multisample
+         ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: -1;
    default:
       return -1;
    }
@@ -1494,6 +1532,7 @@ _mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset,
          break;
       case GL_TEXTURE_2D_ARRAY:
       case GL_TEXTURE_CUBE_MAP_ARRAY:
+      case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
          xBorder = image->Border;
          yBorder = image->Border;
          zBorder = 0;
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index bc66bb3..120845b 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -966,6 +966,9 @@ legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target)
        * "target may also be TEXTURE_BUFFER, indicating the texture buffer."
        */
       return ctx->API == API_OPENGL_CORE && ctx->Version >= 31;
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
+      return ctx->Extensions.ARB_texture_multisample;
    default:
       return GL_FALSE;
    }
@@ -1105,6 +1108,19 @@ get_tex_level_parameter_image(struct gl_context *ctx,
 	    *params = GL_NONE;
          break;
 
+      /* GL_ARB_texture_multisample */
+      case GL_TEXTURE_SAMPLES:
+         if (!ctx->Extensions.ARB_texture_multisample)
+            goto invalid_pname;
+         *params = img->NumSamples;
+         break;
+
+      case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
+         if (!ctx->Extensions.ARB_texture_multisample)
+            goto invalid_pname;
+         *params = img->FixedSampleLocations;
+         break;
+
       default:
          goto invalid_pname;
    }
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 9e591d3..1bd9f91 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -707,6 +707,8 @@ alloc_proxy_textures( struct gl_context *ctx )
     * values!
     */
    static const GLenum targets[] = {
+      GL_TEXTURE_2D_MULTISAMPLE,
+      GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
       GL_TEXTURE_CUBE_MAP_ARRAY,
       GL_TEXTURE_BUFFER,
       GL_TEXTURE_2D_ARRAY_EXT,
-- 
1.8.1.4



More information about the mesa-dev mailing list