[Mesa-dev] [PATCH v3 2/3] mesa/st: add ARB_texture_view support

Roland Scheidegger sroland at vmware.com
Tue Sep 9 07:23:00 PDT 2014


Looks good to me if there's no piglit regressions.

Reviewed-by: Roland Scheidegger <sroland at vmware.com>

Am 09.09.2014 02:59, schrieb Ilia Mirkin:
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> 
> Roland, it was unclear to me whether you were happy with this change or not.
> 
> v2 -> v3:
>  no change
> 
>  src/mesa/state_tracker/st_atom_texture.c | 30 ++++++++++++----
>  src/mesa/state_tracker/st_cb_fbo.c       | 10 ++++++
>  src/mesa/state_tracker/st_cb_texture.c   | 62 +++++++++++++++++++++++++++-----
>  src/mesa/state_tracker/st_extensions.c   |  1 +
>  src/mesa/state_tracker/st_format.c       |  5 +--
>  src/mesa/state_tracker/st_texture.c      | 15 ++++++--
>  6 files changed, 105 insertions(+), 18 deletions(-)
> 
> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
> index 03d0593..ed9a444 100644
> --- a/src/mesa/state_tracker/st_atom_texture.c
> +++ b/src/mesa/state_tracker/st_atom_texture.c
> @@ -192,9 +192,9 @@ get_texture_format_swizzle(const struct st_texture_object *stObj)
>     return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
>  }
>  
> -                            
> +
>  /**
> - * Return TRUE if the texture's sampler view swizzle is equal to
> + * Return TRUE if the texture's sampler view swizzle is not equal to
>   * the texture's swizzle.
>   *
>   * \param stObj  the st texture object,
> @@ -214,9 +214,20 @@ check_sampler_swizzle(const struct st_texture_object *stObj,
>  
>  static unsigned last_level(struct st_texture_object *stObj)
>  {
> -   return MIN2(stObj->base._MaxLevel, stObj->pt->last_level);
> +   unsigned ret = MIN2(stObj->base.MinLevel + stObj->base._MaxLevel,
> +                       stObj->pt->last_level);
> +   if (stObj->base.Immutable)
> +      ret = MIN2(ret, stObj->base.MinLevel + stObj->base.NumLevels - 1);
> +   return ret;
>  }
>  
> +static unsigned last_layer(struct st_texture_object *stObj)
> +{
> +   if (stObj->base.Immutable)
> +      return MIN2(stObj->base.MinLayer + stObj->base.NumLayers - 1,
> +                  stObj->pt->array_size - 1);
> +   return stObj->pt->array_size - 1;
> +}
>  
>  static struct pipe_sampler_view *
>  st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
> @@ -249,9 +260,13 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
>        templ.u.buf.first_element = f;
>        templ.u.buf.last_element  = f + (n - 1);
>     } else {
> -      templ.u.tex.first_level = stObj->base.BaseLevel;
> +      templ.u.tex.first_level = stObj->base.MinLevel + stObj->base.BaseLevel;
>        templ.u.tex.last_level = last_level(stObj);
>        assert(templ.u.tex.first_level <= templ.u.tex.last_level);
> +      templ.u.tex.first_layer = stObj->base.MinLayer;
> +      templ.u.tex.last_layer = last_layer(stObj);
> +      assert(templ.u.tex.first_layer <= templ.u.tex.last_layer);
> +      templ.target = gl_target_to_pipe(stObj->base.Target);
>     }
>  
>     if (swizzle != SWIZZLE_NOOP) {
> @@ -287,8 +302,11 @@ st_get_texture_sampler_view_from_stobj(struct st_context *st,
>     if (*sv) {
>        if (check_sampler_swizzle(stObj, *sv) ||
>  	  (format != (*sv)->format) ||
> -          stObj->base.BaseLevel != (*sv)->u.tex.first_level ||
> -          last_level(stObj) != (*sv)->u.tex.last_level) {
> +          gl_target_to_pipe(stObj->base.Target) != (*sv)->target ||
> +          stObj->base.MinLevel + stObj->base.BaseLevel != (*sv)->u.tex.first_level ||
> +          last_level(stObj) != (*sv)->u.tex.last_level ||
> +          stObj->base.MinLayer != (*sv)->u.tex.first_layer ||
> +          last_layer(stObj) != (*sv)->u.tex.last_layer) {
>  	 pipe_sampler_view_reference(sv, NULL);
>        }
>     }
> diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
> index 7cfd3da..470ab27 100644
> --- a/src/mesa/state_tracker/st_cb_fbo.c
> +++ b/src/mesa/state_tracker/st_cb_fbo.c
> @@ -450,6 +450,16 @@ st_update_renderbuffer_surface(struct st_context *st,
>        last_layer = strb->rtt_face + strb->rtt_slice;
>     }
>  
> +   /* Adjust for texture views */
> +   if (strb->is_rtt) {
> +      struct gl_texture_object *tex = strb->Base.TexImage->TexObject;
> +      first_layer += tex->MinLayer;
> +      if (!strb->rtt_layered)
> +         last_layer += tex->MinLayer;
> +      else
> +         last_layer = MIN2(first_layer + tex->NumLayers - 1, last_layer);
> +   }
> +
>     if (!strb->surface ||
>         strb->surface->texture->nr_samples != strb->Base.NumSamples ||
>         strb->surface->format != format ||
> diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
> index ad14bd9..dfa188a 100644
> --- a/src/mesa/state_tracker/st_cb_texture.c
> +++ b/src/mesa/state_tracker/st_cb_texture.c
> @@ -829,12 +829,12 @@ st_TexSubImage(struct gl_context *ctx, GLuint dims,
>     blit.src.level = 0;
>     blit.src.format = src_format;
>     blit.dst.resource = dst;
> -   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
> +   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->TexObject->MinLevel + texImage->Level;
>     blit.dst.format = dst_format;
>     blit.src.box.x = blit.src.box.y = blit.src.box.z = 0;
>     blit.dst.box.x = xoffset;
>     blit.dst.box.y = yoffset;
> -   blit.dst.box.z = zoffset + texImage->Face;
> +   blit.dst.box.z = zoffset + texImage->Face + texImage->TexObject->MinLayer;
>     blit.src.box.width = blit.dst.box.width = width;
>     blit.src.box.height = blit.dst.box.height = height;
>     blit.src.box.depth = blit.dst.box.depth = depth;
> @@ -916,7 +916,8 @@ st_GetTexImage(struct gl_context * ctx,
>     GLuint height = texImage->Height;
>     GLuint depth = texImage->Depth;
>     struct st_texture_image *stImage = st_texture_image(texImage);
> -   struct pipe_resource *src = st_texture_object(texImage->TexObject)->pt;
> +   struct st_texture_object *stObj = st_texture_object(texImage->TexObject);
> +   struct pipe_resource *src = stObj->pt;
>     struct pipe_resource *dst = NULL;
>     struct pipe_resource dst_templ;
>     enum pipe_format dst_format, src_format;
> @@ -970,7 +971,10 @@ st_GetTexImage(struct gl_context * ctx,
>      * - Luminance alpha must be returned as (L,0,0,A).
>      * - Intensity must be returned as (I,0,0,1)
>      */
> -   src_format = util_format_linear(src->format);
> +   if (stObj->surface_based)
> +      src_format = util_format_linear(stObj->surface_format);
> +   else
> +      src_format = util_format_linear(src->format);
>     src_format = util_format_luminance_to_red(src_format);
>     src_format = util_format_intensity_to_red(src_format);
>  
> @@ -1069,14 +1073,14 @@ st_GetTexImage(struct gl_context * ctx,
>  
>     memset(&blit, 0, sizeof(blit));
>     blit.src.resource = src;
> -   blit.src.level = texImage->Level;
> +   blit.src.level = texImage->Level + texImage->TexObject->MinLevel;
>     blit.src.format = src_format;
>     blit.dst.resource = dst;
>     blit.dst.level = 0;
>     blit.dst.format = dst->format;
>     blit.src.box.x = blit.dst.box.x = 0;
>     blit.src.box.y = blit.dst.box.y = 0;
> -   blit.src.box.z = texImage->Face;
> +   blit.src.box.z = texImage->Face + texImage->TexObject->MinLayer;
>     blit.dst.box.z = 0;
>     blit.src.box.width = blit.dst.box.width = width;
>     blit.src.box.height = blit.dst.box.height = height;
> @@ -1441,10 +1445,10 @@ st_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
>     blit.src.box.depth = 1;
>     blit.dst.resource = stImage->pt;
>     blit.dst.format = dst_format;
> -   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level;
> +   blit.dst.level = stObj->pt != stImage->pt ? 0 : texImage->Level + texImage->TexObject->MinLevel;
>     blit.dst.box.x = destX;
>     blit.dst.box.y = destY;
> -   blit.dst.box.z = stImage->base.Face + slice;
> +   blit.dst.box.z = stImage->base.Face + slice + texImage->TexObject->MinLayer;
>     blit.dst.box.width = width;
>     blit.dst.box.height = height;
>     blit.dst.box.depth = 1;
> @@ -1545,6 +1549,9 @@ st_finalize_texture(struct gl_context *ctx,
>     enum pipe_format firstImageFormat;
>     GLuint ptWidth, ptHeight, ptDepth, ptLayers, ptNumSamples;
>  
> +   if (tObj->Immutable)
> +      return GL_TRUE;
> +
>     if (_mesa_is_texture_complete(tObj, &tObj->Sampler)) {
>        /* The texture is complete and we know exactly how many mipmap levels
>         * are present/needed.  This is conditional because we may be called
> @@ -1824,6 +1831,44 @@ st_TestProxyTexImage(struct gl_context *ctx, GLenum target,
>     }
>  }
>  
> +static GLboolean
> +st_TextureView(struct gl_context *ctx,
> +               struct gl_texture_object *texObj,
> +               struct gl_texture_object *origTexObj)
> +{
> +   struct st_texture_object *orig = st_texture_object(origTexObj);
> +   struct st_texture_object *tex = st_texture_object(texObj);
> +   struct gl_texture_image *image = texObj->Image[0][0];
> +
> +   const int numFaces = _mesa_num_tex_faces(texObj->Target);
> +   const int numLevels = texObj->NumLevels;
> +
> +   int face;
> +   int level;
> +
> +   pipe_resource_reference(&tex->pt, orig->pt);
> +
> +   /* Set image resource pointers */
> +   for (level = 0; level < numLevels; level++) {
> +      for (face = 0; face < numFaces; face++) {
> +         struct st_texture_image *stImage =
> +            st_texture_image(texObj->Image[face][level]);
> +         pipe_resource_reference(&stImage->pt, tex->pt);
> +      }
> +   }
> +
> +   tex->surface_based = GL_TRUE;
> +   tex->surface_format =
> +      st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat);
> +
> +   tex->width0 = image->Width;
> +   tex->height0 = image->Height;
> +   tex->depth0 = image->Depth;
> +   tex->lastLevel = numLevels - 1;
> +
> +   return GL_TRUE;
> +}
> +
>  
>  void
>  st_init_texture_functions(struct dd_function_table *functions)
> @@ -1855,4 +1900,5 @@ st_init_texture_functions(struct dd_function_table *functions)
>     functions->TestProxyTexImage = st_TestProxyTexImage;
>  
>     functions->AllocTextureStorage = st_AllocTextureStorage;
> +   functions->TextureView = st_TextureView;
>  }
> diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
> index 07bd125..c7bc0ca 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -463,6 +463,7 @@ void st_init_extensions(struct pipe_screen *screen,
>        { o(ARB_draw_indirect),                PIPE_CAP_DRAW_INDIRECT                    },
>        { o(ARB_derivative_control),           PIPE_CAP_TGSI_FS_FINE_DERIVATIVE          },
>        { o(ARB_conditional_render_inverted),  PIPE_CAP_CONDITIONAL_RENDER_INVERTED      },
> +      { o(ARB_texture_view),                 PIPE_CAP_SAMPLER_VIEW_TARGET              },
>     };
>  
>     /* Required: render target and sampler support */
> diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
> index b5e03b0..531bc65 100644
> --- a/src/mesa/state_tracker/st_format.c
> +++ b/src/mesa/state_tracker/st_format.c
> @@ -879,6 +879,7 @@ struct format_mapping
>  
>  #define DEFAULT_SRGBA_FORMATS \
>        PIPE_FORMAT_B8G8R8A8_SRGB, \
> +      PIPE_FORMAT_R8G8B8A8_SRGB, \
>        PIPE_FORMAT_A8R8G8B8_SRGB, \
>        PIPE_FORMAT_A8B8G8R8_SRGB, \
>        0
> @@ -919,11 +920,11 @@ static const struct format_mapping format_map[] = {
>     },
>     {
>        { 4, GL_RGBA, GL_RGBA8, 0 },
> -      { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS }
> +      { DEFAULT_RGBA_FORMATS }
>     },
>     {
>        { GL_BGRA, 0 },
> -      { PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGBA_FORMATS }
> +      { DEFAULT_RGBA_FORMATS }
>     },
>     {
>        { 3, GL_RGB, GL_RGB8, 0 },
> diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
> index af9b767..c84aa45 100644
> --- a/src/mesa/state_tracker/st_texture.c
> +++ b/src/mesa/state_tracker/st_texture.c
> @@ -260,6 +260,12 @@ st_texture_image_map(struct st_context *st, struct st_texture_image *stImage,
>     else
>        level = stImage->base.Level;
>  
> +   if (stObj->base.Immutable) {
> +      level += stObj->base.MinLevel;
> +      z += stObj->base.MinLayer;
> +      d = MIN2(d, stObj->base.NumLayers);
> +   }
> +
>     z += stImage->base.Face;
>  
>     map = pipe_transfer_map_3d(st->pipe, stImage->pt, level, usage,
> @@ -289,8 +295,13 @@ st_texture_image_unmap(struct st_context *st,
>                         struct st_texture_image *stImage, unsigned slice)
>  {
>     struct pipe_context *pipe = st->pipe;
> -   struct pipe_transfer **transfer =
> -      &stImage->transfer[slice + stImage->base.Face].transfer;
> +   struct st_texture_object *stObj =
> +      st_texture_object(stImage->base.TexObject);
> +   struct pipe_transfer **transfer;
> +
> +   if (stObj->base.Immutable)
> +      slice += stObj->base.MinLayer;
> +   transfer = &stImage->transfer[slice + stImage->base.Face].transfer;
>  
>     DBG("%s\n", __FUNCTION__);
>  
> 



More information about the mesa-dev mailing list