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

Ian Romanick idr at freedesktop.org
Mon Apr 8 10:48:44 PDT 2013


On 04/06/2013 03:05 AM, Dave Airlie wrote:
> 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.
>
> Reviewed-by: Marek Olšák <maraeo at gmail.com>
> 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       |  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 );
>
>
>



More information about the mesa-dev mailing list