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

Roland Scheidegger sroland at vmware.com
Wed Aug 20 08:25:41 PDT 2014


Didn't look at it that closely, but I'm pretty surprised this really
works. One things ARB_texture_view can do is cast cube maps (and cube
map arrays) to 2d arrays and vice versa (also 1d/2d to the respective
array type), and we cannot express that in sampler views (yet) (we can't
express it in surfaces neither but there it should not matter). Which
means the type used in the shader for sampling will not match the
sampler view, which sounds quite broken to me.

Roland

Am 20.08.2014 08:45, schrieb Ilia Mirkin:
> Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
> ---
> 
> No piglit regressions on nvc0 except for gl-3.0-render-integer, which appears
> to now fail even without this commit, despite the fact that I'm fairly sure it
> used to work fine. Same failure with llvmpipe...
> 
> It's most likely that I've missed some details. It's unclear whether
> e.g. glGenerateMipmap should work on a view. However the piglits that exist do
> all pass on nvc0 and llvmpipe.
> 
>  docs/GL3.txt                             |  2 +-
>  docs/relnotes/10.3.html                  |  1 +
>  src/mesa/state_tracker/st_atom_texture.c | 28 +++++++++++----
>  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 ++++++--
>  8 files changed, 105 insertions(+), 19 deletions(-)
> 
> diff --git a/docs/GL3.txt b/docs/GL3.txt
> index 76412c3..5b25865 100644
> --- a/docs/GL3.txt
> +++ b/docs/GL3.txt
> @@ -166,7 +166,7 @@ GL 4.3, GLSL 4.30:
>    GL_ARB_texture_buffer_range                          DONE (nv50, nvc0, i965, r600, radeonsi)
>    GL_ARB_texture_query_levels                          DONE (all drivers that support GLSL 1.30)
>    GL_ARB_texture_storage_multisample                   DONE (all drivers that support GL_ARB_texture_multisample)
> -  GL_ARB_texture_view                                  DONE (i965)
> +  GL_ARB_texture_view                                  DONE (i965, nv30, nv50, nvc0, r300, r600, radeonsi, llvmpipe, softpipe)
>    GL_ARB_vertex_attrib_binding                         DONE (all drivers)
>  
>  
> diff --git a/docs/relnotes/10.3.html b/docs/relnotes/10.3.html
> index fa4ea23..852aec9 100644
> --- a/docs/relnotes/10.3.html
> +++ b/docs/relnotes/10.3.html
> @@ -63,6 +63,7 @@ Note: some of the new features are only available with certain drivers.
>  <li>GL_ARB_texture_gather on r600, radeonsi</li>
>  <li>GL_ARB_texture_query_levels on nv50, nvc0, llvmpipe, r600, radeonsi, softpipe</li>
>  <li>GL_ARB_texture_query_lod on r600, radeonsi</li>
> +<li>GL_ARB_texture_view on nv30, nv50, nvc0, r300, r600, radeonsi, llvmpipe, softpipe</li>
>  <li>GL_ARB_viewport_array on nvc0</li>
>  <li>GL_AMD_vertex_shader_viewport_index on i965/gen7+, r600</li>
>  <li>GL_OES_compressed_ETC1_RGB8_texture on nv30, nv50, nvc0, r300, r600, radeonsi, softpipe, llvmpipe</li>
> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
> index 03d0593..8f62494 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,12 @@ 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);
>     }
>  
>     if (swizzle != SWIZZLE_NOOP) {
> @@ -287,8 +301,10 @@ 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) {
> +          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 4110eb5..557d54f 100644
> --- a/src/mesa/state_tracker/st_extensions.c
> +++ b/src/mesa/state_tracker/st_extensions.c
> @@ -597,6 +597,7 @@ void st_init_extensions(struct pipe_screen *screen,
>     extensions->ARB_texture_env_combine = GL_TRUE;
>     extensions->ARB_texture_env_crossbar = GL_TRUE;
>     extensions->ARB_texture_env_dot3 = GL_TRUE;
> +   extensions->ARB_texture_view = GL_TRUE;
>     extensions->ARB_vertex_program = GL_TRUE;
>     extensions->ARB_vertex_shader = GL_TRUE;
>  
> 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