On 04/06/2013 03:05 AM, Dave Airlie wrote:
From: Dave Airlie <airl...@redhat.com>

This adds support to the mesa state tracker for ARB_texture_multisample.

hardware doesn't seem to use a different texture instructions, so
I don't think we need to create one for TGSI at this time.

Thanks to Marek for fixes to sample number picking.

Reviewed-by: Marek Olšák <mar...@gmail.com>
Signed-off-by: Dave Airlie <airl...@redhat.com>
---
  src/mesa/state_tracker/st_atom_framebuffer.c |  1 +
  src/mesa/state_tracker/st_atom_msaa.c        |  2 ++
  src/mesa/state_tracker/st_cb_bitmap.c        |  4 +--
  src/mesa/state_tracker/st_cb_drawpixels.c    |  2 +-
  src/mesa/state_tracker/st_cb_fbo.c           |  2 +-
  src/mesa/state_tracker/st_cb_texture.c       | 41 ++++++++++++++++++++++++----
  src/mesa/state_tracker/st_extensions.c       |  6 +++-
  src/mesa/state_tracker/st_gen_mipmap.c       |  1 +
  src/mesa/state_tracker/st_glsl_to_tgsi.cpp   | 17 ++++++++++--
  src/mesa/state_tracker/st_mesa_to_tgsi.c     |  2 ++
  src/mesa/state_tracker/st_texture.c          |  8 +++++-
  src/mesa/state_tracker/st_texture.h          |  1 +
  12 files changed, 72 insertions(+), 15 deletions(-)

diff --git a/src/mesa/state_tracker/st_atom_framebuffer.c 
b/src/mesa/state_tracker/st_atom_framebuffer.c
index 3df8691..c752640 100644
--- a/src/mesa/state_tracker/st_atom_framebuffer.c
+++ b/src/mesa/state_tracker/st_atom_framebuffer.c
@@ -59,6 +59,7 @@ update_renderbuffer_surface(struct st_context *st,
     enum pipe_format format = st->ctx->Color.sRGBEnabled ? resource->format : 
util_format_linear(resource->format);

     if (!strb->surface ||
+       strb->surface->texture->nr_samples != strb->Base.NumSamples ||
         strb->surface->format != format ||
         strb->surface->texture != resource ||
         strb->surface->width != rtt_width ||
diff --git a/src/mesa/state_tracker/st_atom_msaa.c 
b/src/mesa/state_tracker/st_atom_msaa.c
index 9baa4fc..b749a17 100644
--- a/src/mesa/state_tracker/st_atom_msaa.c
+++ b/src/mesa/state_tracker/st_atom_msaa.c
@@ -63,6 +63,8 @@ static void update_sample_mask( struct st_context *st )
              sample_mask = ~sample_mask;
        }
        /* TODO merge with app-supplied sample mask */
+      if (st->ctx->Multisample.SampleMask)
+         sample_mask = st->ctx->Multisample.SampleMaskValue;
     }

     /* mask off unused bits or don't care? */
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c 
b/src/mesa/state_tracker/st_cb_bitmap.c
index 0513814..ee66ab3 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -299,7 +299,7 @@ make_bitmap_texture(struct gl_context *ctx, GLsizei width, 
GLsizei height,
      * Create texture to hold bitmap pattern.
      */
     pt = st_texture_create(st, st->internal_target, st->bitmap.tex_format,
-                          0, width, height, 1, 1,
+                          0, width, height, 1, 1, 0,
                            PIPE_BIND_SAMPLER_VIEW);
     if (!pt) {
        _mesa_unmap_pbo_source(ctx, unpack);
@@ -568,7 +568,7 @@ reset_cache(struct st_context *st)
     cache->texture = st_texture_create(st, PIPE_TEXTURE_2D,
                                        st->bitmap.tex_format, 0,
                                        BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
-                                      1, 1,
+                                      1, 1, 0,
                                      PIPE_BIND_SAMPLER_VIEW);
  }

diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c 
b/src/mesa/state_tracker/st_cb_drawpixels.c
index b25b776..db2f03a 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -466,7 +466,7 @@ alloc_texture(struct st_context *st, GLsizei width, GLsizei 
height,
     struct pipe_resource *pt;

     pt = st_texture_create(st, st->internal_target, texFormat, 0,
-                          width, height, 1, 1, PIPE_BIND_SAMPLER_VIEW);
+                          width, height, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW);

     return pt;
  }
diff --git a/src/mesa/state_tracker/st_cb_fbo.c 
b/src/mesa/state_tracker/st_cb_fbo.c
index 4452e52..127b123 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -433,7 +433,7 @@ st_render_texture(struct gl_context *ctx,
     strb->rtt_level = att->TextureLevel;
     strb->rtt_face = att->CubeMapFace;
     strb->rtt_slice = att->Zoffset;
-
+   rb->NumSamples = texImage->NumSamples;
     rb->Width = texImage->Width2;
     rb->Height = texImage->Height2;
     rb->_BaseFormat = texImage->_BaseFormat;
diff --git a/src/mesa/state_tracker/st_cb_texture.c 
b/src/mesa/state_tracker/st_cb_texture.c
index 0cd0d77..25ee352 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -78,6 +78,8 @@ gl_target_to_pipe(GLenum target)
     case GL_TEXTURE_2D:
     case GL_PROXY_TEXTURE_2D:
     case GL_TEXTURE_EXTERNAL_OES:
+   case GL_TEXTURE_2D_MULTISAMPLE:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
        return PIPE_TEXTURE_2D;
     case GL_TEXTURE_RECTANGLE_NV:
     case GL_PROXY_TEXTURE_RECTANGLE_NV:
@@ -99,6 +101,8 @@ gl_target_to_pipe(GLenum target)
        return PIPE_TEXTURE_1D_ARRAY;
     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:
        return PIPE_TEXTURE_2D_ARRAY;
     case GL_TEXTURE_BUFFER:
        return PIPE_BUFFER;
@@ -408,7 +412,7 @@ guess_and_alloc_texture(struct st_context *st,
                                   ptWidth,
                                   ptHeight,
                                   ptDepth,
-                                 ptLayers,
+                                 ptLayers, 0,
                                   bindings);

     stObj->lastLevel = lastLevel;
@@ -496,7 +500,7 @@ st_AllocTextureImageBuffer(struct gl_context *ctx,
                                        ptWidth,
                                        ptHeight,
                                        ptDepth,
-                                      ptLayers,
+                                      ptLayers, 0,
                                        bindings);
        return stImage->pt != NULL;
     }
@@ -1492,7 +1496,7 @@ st_finalize_texture(struct gl_context *ctx,
     GLuint face;
     struct st_texture_image *firstImage;
     enum pipe_format firstImageFormat;
-   GLuint ptWidth, ptHeight, ptDepth, ptLayers;
+   GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;

     if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
        /* The texture is complete and we know exactly how many mipmap levels
@@ -1556,6 +1560,7 @@ st_finalize_texture(struct gl_context *ctx,
        /* convert GL dims to Gallium dims */
        st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, 
depth,
                                        &ptWidth, &ptHeight, &ptDepth, 
&ptLayers);
+      ptNumSamples = firstImage->base.NumSamples;
     }

     /* If we already have a gallium texture, check that it matches the texture
@@ -1568,6 +1573,7 @@ st_finalize_texture(struct gl_context *ctx,
            stObj->pt->width0 != ptWidth ||
            stObj->pt->height0 != ptHeight ||
            stObj->pt->depth0 != ptDepth ||
+          stObj->pt->nr_samples != ptNumSamples ||
            stObj->pt->array_size != ptLayers)
        {
           /* The gallium texture does not match the Mesa texture so delete the
@@ -1591,7 +1597,7 @@ st_finalize_texture(struct gl_context *ctx,
                                      ptWidth,
                                      ptHeight,
                                      ptDepth,
-                                    ptLayers,
+                                    ptLayers, ptNumSamples,
                                      bindings);

        if (!stObj->pt) {
@@ -1637,11 +1643,14 @@ st_AllocTextureStorage(struct gl_context *ctx,
                         GLsizei height, GLsizei depth)
  {
     const GLuint numFaces = _mesa_num_tex_faces(texObj->Target);
+   struct gl_texture_image *texImage = texObj->Image[0][0];
     struct st_context *st = st_context(ctx);
     struct st_texture_object *stObj = st_texture_object(texObj);
+   struct pipe_screen *screen = st->pipe->screen;
     GLuint ptWidth, ptHeight, ptDepth, ptLayers, bindings;
     enum pipe_format fmt;
     GLint level;
+   int num_samples = texImage->NumSamples;

     assert(levels > 0);

@@ -1651,10 +1660,30 @@ st_AllocTextureStorage(struct gl_context *ctx,
     stObj->depth0 = depth;
     stObj->lastLevel = levels - 1;

-   fmt = st_mesa_format_to_pipe_format(texObj->Image[0][0]->TexFormat);
+   fmt = st_mesa_format_to_pipe_format(texImage->TexFormat);

     bindings = default_bindings(st, fmt);

+   /* Raise the sample count if the requested one is unsupported. */
+   if (num_samples > 1) {
+      boolean found = FALSE;
+
+      for (; num_samples <= ctx->Const.MaxSamples; num_samples++) {
+         if (screen->is_format_supported(screen, fmt, PIPE_TEXTURE_2D,
+                                         num_samples,
+                                         PIPE_BIND_SAMPLER_VIEW)) {
+            /* Update the sample count in gl_texture_image as well. */
+            texImage->NumSamples = num_samples;
+            found = TRUE;
+            break;
+         }
+      }
+
+      if (!found) {
+         return GL_FALSE;
+      }
+   }
+
     st_gl_texture_dims_to_pipe_dims(texObj->Target,
                                     width, height, depth,
                                     &ptWidth, &ptHeight, &ptDepth, &ptLayers);
@@ -1666,7 +1695,7 @@ st_AllocTextureStorage(struct gl_context *ctx,
                                   ptWidth,
                                   ptHeight,
                                   ptDepth,
-                                 ptLayers,
+                                 ptLayers, num_samples,
                                   bindings);
     if (!stObj->pt)
        return GL_FALSE;
diff --git a/src/mesa/state_tracker/st_extensions.c 
b/src/mesa/state_tracker/st_extensions.c
index 11db9d3..6f0e253 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -398,7 +398,8 @@ void st_init_extensions(struct st_context *st)
        { o(MESA_texture_array),               
PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS         },

        { o(OES_standard_derivatives),         PIPE_CAP_SM3                     
         },
-      { o(ARB_texture_cube_map_array),       PIPE_CAP_CUBE_MAP_ARRAY           
        }
+      { o(ARB_texture_cube_map_array),       PIPE_CAP_CUBE_MAP_ARRAY           
        },
+      { o(ARB_texture_multisample),          PIPE_CAP_TEXTURE_MULTISAMPLE      
        }
     };

     /* Required: render target and sampler support */
@@ -651,6 +652,9 @@ void st_init_extensions(struct st_context *st)
                                        PIPE_TEXTURE_2D, i,
                                        PIPE_BIND_RENDER_TARGET)) {
           ctx->Const.MaxSamples = i;
+         ctx->Const.MaxColorTextureSamples = i;
+         ctx->Const.MaxDepthTextureSamples = i;
+         ctx->Const.MaxIntegerSamples = i;

I don't think this is right. Won't this cause the driver to advertise, say, 4-sample integer rendering based only on 4-sample UNORM support? I could have sworn that at least some AMD hardware could do UNORM multisampling but couldn't do integer multisampling at all. I think this will also cause glGetInternalformativ(..., GL_RGBA_8I, GL_SAMPLES, ...) to return a smaller number than glGetIntegerv(GL_MAX_INTEGER_SAMPLES, ...). Right?

           break;
        }
     }
diff --git a/src/mesa/state_tracker/st_gen_mipmap.c 
b/src/mesa/state_tracker/st_gen_mipmap.c
index 8ce2e06..e5512af 100644
--- a/src/mesa/state_tracker/st_gen_mipmap.c
+++ b/src/mesa/state_tracker/st_gen_mipmap.c
@@ -172,6 +172,7 @@ st_generate_mipmap(struct gl_context *ctx, GLenum target,
                                      oldTex->height0,
                                      oldTex->depth0,
                                      oldTex->array_size,
+                                    0,
                                      oldTex->bind);

        /* This will copy the old texture's base image into the new texture
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp 
b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 338c652..589c912 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2683,7 +2683,7 @@ glsl_to_tgsi_visitor::visit(ir_call *ir)
  void
  glsl_to_tgsi_visitor::visit(ir_texture *ir)
  {
-   st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset;
+   st_src_reg result_src, coord, cube_sc, lod_info, projector, dx, dy, offset, 
sample_index;
     st_dst_reg result_dst, coord_dst, cube_sc_dst;
     glsl_to_tgsi_instruction *inst = NULL;
     unsigned opcode = TGSI_OPCODE_NOP;
@@ -2706,6 +2706,7 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
         */
        coord = get_temp(glsl_type::vec4_type);
        coord_dst = st_dst_reg(coord);
+      coord_dst.writemask = (1 << ir->coordinate->type->vector_elements) - 1;
        emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
     }

@@ -2772,7 +2773,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
        }
        break;
     case ir_txf_ms:
-      assert(!"Unexpected ir_txf_ms opcode");
+      opcode = TGSI_OPCODE_TXF;
+      ir->lod_info.sample_index->accept(this);
+      sample_index = this->result;
        break;
     case ir_lod:
        assert(!"Unexpected ir_lod opcode");
@@ -2859,7 +2862,11 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
        }
     }

-   if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB ||
+   if (ir->op == ir_txf_ms) {
+      coord_dst.writemask = WRITEMASK_W;
+      emit(ir, TGSI_OPCODE_MOV, coord_dst, sample_index);
+      coord_dst.writemask = WRITEMASK_XYZW;
+   } else if (opcode == TGSI_OPCODE_TXL || opcode == TGSI_OPCODE_TXB ||
         opcode == TGSI_OPCODE_TXF) {
        /* TGSI stores LOD or LOD bias in the last channel of the coords. */
        coord_dst.writemask = WRITEMASK_W;
@@ -2921,6 +2928,10 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
     case GLSL_SAMPLER_DIM_EXTERNAL:
        inst->tex_target = TEXTURE_EXTERNAL_INDEX;
        break;
+   case GLSL_SAMPLER_DIM_MS:
+      inst->tex_target = (sampler_type->sampler_array)
+         ? TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX : TEXTURE_2D_MULTISAMPLE_INDEX;
+      break;
     default:
        assert(!"Should not get here.");
     }
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c 
b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 3831a0a..5471a9a 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -269,6 +269,8 @@ st_translate_texture_target( GLuint textarget,
     }

     switch( textarget ) {
+   case TEXTURE_2D_MULTISAMPLE_INDEX: return TGSI_TEXTURE_2D_MSAA;
+   case TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX: return TGSI_TEXTURE_2D_ARRAY_MSAA;
     case TEXTURE_BUFFER_INDEX: return TGSI_TEXTURE_BUFFER;
     case TEXTURE_1D_INDEX:   return TGSI_TEXTURE_1D;
     case TEXTURE_2D_INDEX:   return TGSI_TEXTURE_2D;
diff --git a/src/mesa/state_tracker/st_texture.c 
b/src/mesa/state_tracker/st_texture.c
index ed37098..9a27182 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -60,6 +60,7 @@ st_texture_create(struct st_context *st,
                  GLuint height0,
                  GLuint depth0,
                    GLuint layers,
+                  GLuint nr_samples,
                    GLuint bind )
  {
     struct pipe_resource pt, *newtex;
@@ -90,6 +91,7 @@ st_texture_create(struct st_context *st,
     pt.usage = PIPE_USAGE_DEFAULT;
     pt.bind = bind;
     pt.flags = 0;
+   pt.nr_samples = nr_samples;

     newtex = screen->resource_create(screen, &pt);

@@ -138,6 +140,8 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture,
     case GL_TEXTURE_RECTANGLE:
     case GL_PROXY_TEXTURE_RECTANGLE:
     case GL_TEXTURE_EXTERNAL_OES:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE:
+   case GL_TEXTURE_2D_MULTISAMPLE:
        assert(depthIn == 1);
        *widthOut = widthIn;
        *heightOut = heightIn;
@@ -159,7 +163,9 @@ st_gl_texture_dims_to_pipe_dims(GLenum texture,
        *layersOut = 6;
        break;
     case GL_TEXTURE_2D_ARRAY:
+   case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
     case GL_PROXY_TEXTURE_2D_ARRAY:
+   case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY:
        *widthOut = widthIn;
        *heightOut = heightIn;
        *depthOut = 1;
@@ -402,7 +408,7 @@ st_create_color_map_texture(struct gl_context *ctx)

     /* create texture for color map/table */
     pt = st_texture_create(st, PIPE_TEXTURE_2D, format, 0,
-                          texSize, texSize, 1, 1, PIPE_BIND_SAMPLER_VIEW);
+                          texSize, texSize, 1, 1, 0, PIPE_BIND_SAMPLER_VIEW);
     return pt;
  }

diff --git a/src/mesa/state_tracker/st_texture.h 
b/src/mesa/state_tracker/st_texture.h
index 8a70100..da899c9 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -153,6 +153,7 @@ st_texture_create(struct st_context *st,
                    GLuint height0,
                    GLuint depth0,
                    GLuint layers,
+                  GLuint nr_samples,
                    GLuint tex_usage );




_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to