[Mesa-dev] [PATCH 3/4] st/mesa: add support for ARB_texture_multisample

Dave Airlie airlied at gmail.com
Sun Mar 3 12:27:53 PST 2013


From: Dave Airlie <airlied at 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.

Signed-off-by: Dave Airlie <airlied at 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       |  7 +++++
 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, 74 insertions(+), 14 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 36fffe9..d7a95e2 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 e282bf9..e609eb5 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -463,7 +463,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 72bc960..cf3e27f 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -430,7 +430,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 c922a31..385bac6 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;
    }
@@ -1484,7 +1488,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
@@ -1548,6 +1552,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
@@ -1560,6 +1565,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
@@ -1583,7 +1589,7 @@ st_finalize_texture(struct gl_context *ctx,
                                     ptWidth,
                                     ptHeight,
                                     ptDepth,
-                                    ptLayers,
+                                    ptLayers, ptNumSamples,
                                     bindings);
 
       if (!stObj->pt) {
@@ -1629,11 +1635,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);
 
@@ -1643,10 +1652,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);
@@ -1658,7 +1687,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..9526c41 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -651,6 +651,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;
          break;
       }
    }
@@ -712,4 +715,8 @@ void st_init_extensions(struct st_context *st)
       if (!ctx->Extensions.EXT_transform_feedback)
          ctx->Const.DisableVaryingPacking = GL_TRUE;
    }
+
+   if (screen->get_param(screen, PIPE_CAP_TEXTURE_MULTISAMPLE))
+      ctx->Extensions.ARB_texture_multisample = GL_TRUE;
+
 }
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 c41b583..2f69301 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -2674,7 +2674,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;
@@ -2697,6 +2697,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);
    }
 
@@ -2747,7 +2748,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;
    }
 
@@ -2831,7 +2834,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;
@@ -2893,6 +2900,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 e326bcc..b07e37f 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 );
 
 
-- 
1.8.1.2



More information about the mesa-dev mailing list