[Mesa-dev] [PATCH 2/2] st/mesa: overhaul texture / sample swizzle code

Marek Olšák maraeo at gmail.com
Wed Mar 26 17:06:02 PDT 2014


The patch looks good to me. There is hardware which doesn't support
swizzling, but it sure isn't radeon.

Marek

On Thu, Mar 27, 2014 at 12:17 AM, Brian Paul <brianp at vmware.com> wrote:
>
> I haven't investigated fbo-blending-formats but if it's like
> fbo-clear-formats, this fixes the piglit_draw_rect_tex() rendering which
> displays the texture on a test quad.
>
> -Brian
>
>
>
> On 03/26/2014 03:52 PM, Marek Olšák wrote:
>>
>> Is this just a workaround for the fbo-blending-formats test? It should
>> test if GL_DST_ALPHA is equivalent to GL_ONE if the format is RGBX. I
>> don't think the test has anything to do with texturing.
>>
>> Marek
>>
>> On Wed, Mar 26, 2014 at 8:58 PM, Brian Paul <brianp at vmware.com> wrote:
>>>
>>> Previously we only examined the GL_DEPTH_MODE state to determine the
>>> sampler view swizzle for depth textures.  Now we also consider the
>>> texture base format for color textures too.
>>>
>>> The basic idea is if we're sampling from a RGB texture we always
>>> want to get A=1, even if the actual hardware format might be RGBA.
>>> We had assumed that the texture's A values were always one since that's
>>> what Mesa's texstore code does.  But if we render to the RGBA texture,
>>> the A values might not be 1.  Subsequent sampling didn't return the
>>> right values.
>>>
>>> Now we examine the user-specified texture base format vs. the actual
>>> gallium format to determine the right swizzle.
>>>
>>> Fixes several fbo-blending-formats, fbo-clear-formats and fbo-tex-rgbx
>>> failures with VMware/svga driver (and possibly other drivers).
>>> No other piglit regressions with softpipe or VMware/svga.
>>> ---
>>>   src/mesa/state_tracker/st_atom_texture.c |  167
>>> ++++++++++++++++++++----------
>>>   1 file changed, 114 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/src/mesa/state_tracker/st_atom_texture.c
>>> b/src/mesa/state_tracker/st_atom_texture.c
>>> index c445213..c9bffce 100644
>>> --- a/src/mesa/state_tracker/st_atom_texture.c
>>> +++ b/src/mesa/state_tracker/st_atom_texture.c
>>> @@ -83,67 +83,132 @@ swizzle_swizzle(unsigned swizzle1, unsigned
>>> swizzle2)
>>>
>>>
>>>   /**
>>> - * Combine depth texture mode with "swizzle" so that depth mode
>>> swizzling
>>> - * takes place before texture swizzling, and return the resulting
>>> swizzle.
>>> - * If the format is not a depth format, return "swizzle" unchanged.
>>> + * Given a user-specified texture base format, the actual gallium
>>> texture
>>> + * format and the current GL_DEPTH_MODE, return a texture swizzle.
>>>    *
>>> - * \param format     PIPE_FORMAT_*.
>>> - * \param swizzle    Texture swizzle, a bitmask computed using
>>> MAKE_SWIZZLE4.
>>> - * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA,
>>> GL_RED.
>>> + * Consider the case where the user requests a GL_RGB internal texture
>>> + * format the driver actually uses an RGBA format.  The A component
>>> should
>>> + * be ignored and sampling from the texture should always return
>>> (r,g,b,1).
>>> + * But if we rendered to the texture we might have written A values !=
>>> 1.
>>> + * By sampling the texture with a ".xyz1" swizzle we'll get the expected
>>> A=1.
>>> + * This function computes the texture swizzle needed to get the expected
>>> + * values.
>>> + *
>>> + * In the case of depth textures, the GL_DEPTH_MODE state determines the
>>> + * texture swizzle.
>>> + *
>>> + * This result must be composed with the user-specified swizzle to get
>>> + * the final swizzle.
>>>    */
>>> -static GLuint
>>> -apply_depthmode(enum pipe_format format, GLuint swizzle, GLenum
>>> depthmode)
>>> +static unsigned
>>> +compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
>>> +                               enum pipe_format actualFormat)
>>>   {
>>> -   const struct util_format_description *desc =
>>> -         util_format_description(format);
>>> -   unsigned swz;
>>> -
>>> -   if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
>>> -       desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
>>> -      /* Not a depth format. */
>>> -      return swizzle;
>>> -   }
>>> -
>>> -   switch (depthmode) {
>>> +   switch (baseFormat) {
>>> +   case GL_RGBA:
>>> +      return SWIZZLE_XYZW;
>>> +   case GL_RGB:
>>> +      if (util_format_has_alpha(actualFormat))
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z,
>>> SWIZZLE_ONE);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>> +   case GL_RG:
>>> +      if (util_format_get_nr_components(actualFormat) > 2)
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO,
>>> SWIZZLE_ONE);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>> +   case GL_RED:
>>> +      if (util_format_get_nr_components(actualFormat) > 1)
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
>>> +                              SWIZZLE_ZERO, SWIZZLE_ONE);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>> +   case GL_ALPHA:
>>> +      if (util_format_get_nr_components(actualFormat) > 1)
>>> +         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
>>> +                              SWIZZLE_ZERO, SWIZZLE_W);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>>      case GL_LUMINANCE:
>>> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
>>> -      break;
>>> +      if (util_format_get_nr_components(actualFormat) > 1)
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,
>>> SWIZZLE_ONE);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>> +   case GL_LUMINANCE_ALPHA:
>>> +      if (util_format_get_nr_components(actualFormat) > 2)
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,
>>> SWIZZLE_W);
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>>      case GL_INTENSITY:
>>> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
>>> -      break;
>>> -   case GL_ALPHA:
>>> -      swz = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO,
>>> SWIZZLE_X);
>>> -      break;
>>> -   case GL_RED:
>>> -      swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO,
>>> SWIZZLE_ONE);
>>> -      break;
>>> +      if (util_format_get_nr_components(actualFormat) > 1)
>>> +         return SWIZZLE_XXXX;
>>> +      else
>>> +         return SWIZZLE_XYZW;
>>> +   case GL_STENCIL_INDEX:
>>> +      return SWIZZLE_XYZW;
>>> +   case GL_DEPTH_STENCIL:
>>> +      /* fall-through */
>>> +   case GL_DEPTH_COMPONENT:
>>> +      /* Now examine the depth mode */
>>> +      switch (depthMode) {
>>> +      case GL_LUMINANCE:
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,
>>> SWIZZLE_ONE);
>>> +      case GL_INTENSITY:
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X,
>>> SWIZZLE_X);
>>> +      case GL_ALPHA:
>>> +         return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
>>> +                              SWIZZLE_ZERO, SWIZZLE_X);
>>> +      case GL_RED:
>>> +         return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
>>> +                              SWIZZLE_ZERO, SWIZZLE_ONE);
>>> +      default:
>>> +         assert(!"Unexpected depthMode");
>>> +         return SWIZZLE_XYZW;
>>> +      }
>>> +   default:
>>> +      assert(!"Unexpected baseFormat");
>>> +      return SWIZZLE_XYZW;
>>>      }
>>> -
>>> -   return swizzle_swizzle(swizzle, swz);
>>>   }
>>>
>>>
>>> +static unsigned
>>> +get_texture_format_swizzle(const struct st_texture_object *stObj)
>>> +{
>>> +   const struct gl_texture_image *texImage =
>>> +      stObj->base.Image[0][stObj->base.BaseLevel];
>>> +   unsigned tex_swizzle;
>>> +
>>> +   if (texImage) {
>>> +      tex_swizzle =
>>> compute_texture_format_swizzle(texImage->_BaseFormat,
>>> +
>>> stObj->base.DepthMode,
>>> +                                                   stObj->pt->format);
>>> +   }
>>> +   else {
>>> +      tex_swizzle = SWIZZLE_XYZW;
>>> +   }
>>> +
>>> +   /* Combine the texture format swizzle with user's swizzle */
>>> +   return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
>>> +}
>>> +
>>> +
>>>   /**
>>> - * Return TRUE if the swizzling described by "swizzle" and
>>> - * "depthmode" (for depth textures only) is different from the swizzling
>>> - * set in the given sampler view.
>>> + * Return TRUE if the texture's sampler view swizzle is equal to
>>> + * the texture's swizzle.
>>>    *
>>> - * \param sv         A sampler view.
>>> - * \param swizzle    Texture swizzle, a bitmask computed using
>>> MAKE_SWIZZLE4.
>>> - * \param depthmode  One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
>>> + * \param stObj  the st texture object,
>>>    */
>>>   static boolean
>>> -check_sampler_swizzle(struct pipe_sampler_view *sv,
>>> -                      GLuint swizzle, GLenum depthmode)
>>> +check_sampler_swizzle(const struct st_texture_object *stObj)
>>>   {
>>> -   swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
>>> -
>>> -   if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
>>> -       (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
>>> -       (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
>>> -       (sv->swizzle_a != GET_SWZ(swizzle, 3)))
>>> -      return TRUE;
>>> -   return FALSE;
>>> +   const struct pipe_sampler_view *sv = stObj->sampler_view;
>>> +   unsigned swizzle = get_texture_format_swizzle(stObj);
>>> +
>>> +   return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
>>> +           (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
>>> +           (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
>>> +           (sv->swizzle_a != GET_SWZ(swizzle, 3)));
>>>   }
>>>
>>>
>>> @@ -154,9 +219,7 @@ st_create_texture_sampler_view_from_stobj(struct
>>> pipe_context *pipe,
>>>                                            enum pipe_format format)
>>>   {
>>>      struct pipe_sampler_view templ;
>>> -   GLuint swizzle = apply_depthmode(stObj->pt->format,
>>> -                                    stObj->base._Swizzle,
>>> -                                    stObj->base.DepthMode);
>>> +   unsigned swizzle = get_texture_format_swizzle(stObj);
>>>
>>>      u_sampler_view_default_template(&templ,
>>>                                      stObj->pt,
>>> @@ -269,9 +332,7 @@ update_single_texture(struct st_context *st,
>>>
>>>      /* if sampler view has changed dereference it */
>>>      if (stObj->sampler_view) {
>>> -      if (check_sampler_swizzle(stObj->sampler_view,
>>> -                               stObj->base._Swizzle,
>>> -                               stObj->base.DepthMode) ||
>>> +      if (check_sampler_swizzle(stObj) ||
>>>            (view_format != stObj->sampler_view->format) ||
>>>            stObj->base.BaseLevel !=
>>> stObj->sampler_view->u.tex.first_level) {
>>>           pipe_sampler_view_release(pipe, &stObj->sampler_view);
>>> --
>>> 1.7.10.4
>>>
>>> _______________________________________________
>>> mesa-dev mailing list
>>> mesa-dev at lists.freedesktop.org
>>>
>>> https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/mesa-dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=lGQMzzTgII0I7jefp2FHq7WtZ%2BTLs8wadB%2BiIj9xpBY%3D%0A&m=sXz9YdJT4PP545fmo2CytUHCpH6BhyGKPB9eYCZ7G04%3D%0A&s=dc146584aafc81ec2b72a97e3fb2b0deecb937fc7c28d4f0e8413e8c143bd358
>
>


More information about the mesa-dev mailing list