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

Brian Paul brianp at vmware.com
Wed Mar 26 16:17:10 PDT 2014


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