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

Ilia Mirkin imirkin at alum.mit.edu
Wed Aug 20 08:31:54 PDT 2014


Hm, it's not tested. And you're right, that would (most likely) mess
up, since it would only have the pipe_resource's target. Any
suggestions on how to fix it? Should the target be added to
pipe_sampler_view?

On Wed, Aug 20, 2014 at 11:25 AM, Roland Scheidegger <sroland at vmware.com> wrote:
> 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