[Mesa-dev] [PATCH] swrast: Fix fixed-function fragment processing

Ian Romanick idr at freedesktop.org
Fri Jan 27 11:02:13 PST 2012


On 01/26/2012 12:46 PM, Chad Versace wrote:
> On i965, _mesa_ir_link_shader is never called. As a consequence, the
> current fragment program (ctx->FragmentProgram->_Current) exists but does
> not differ from the fixed function fragment program
> (ctx->FragmentProgram->_TexEnvProgram). This confuses swrast.
>
> To fix the confusion, this patch replaces checks of the form
>      if (ctx->FragmentProgram->_Current == NULL)
> with
>      if (_swrast_use_fragment_program(ctx))
> when appropriate.
>
> Fixes the following oglconform regressions on i965/gen6:
>      api-fogcoord(basic.allCases.log)
>      api-mtexcoord(basic.allCases.log)
>      api-seccolor(basic.allCases.log)
>      api-texcoord(basic.allCases.log)
>      blend-separate(basic.allCases)
>      colorsum(basic.allCases.log)
>
> The tests were ran with the GLXFBConfig:
>      visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer ms  cav
>    id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat
> ----------------------------------------------------------------------------
> 0x021 24 tc  0  32  0 r  y .   8  8  8  8 .  .  0 24 8  0  0  0  0  0 0 None
>
> (Note: I originally believed that the hunk in
> _swrast_update_fragment_program was unnecessary. But it is required to fix
> blend-separate.)
>
> Note: This is a candidate for the 8.0 branch.
> CC: Ian Romanick<idr at freedesktop.org>

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>

> CC: Eric Anholt<eric at anholt.net>
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=43327
> Signed-off-by: Chad Versace<chad.versace at linux.intel.com>
> ---
>
> Eric, I'm trusting your judgement here, since these parts of swrast are new to
> me.  I've replaced _swrast_fragment_program_is_empty with
> _swrast_use_fragment_program.
>
>   src/mesa/swrast/s_aaline.c     |    2 +-
>   src/mesa/swrast/s_aalinetemp.h |    2 +-
>   src/mesa/swrast/s_aatriangle.c |    2 +-
>   src/mesa/swrast/s_context.c    |   25 ++++++++++++++-----------
>   src/mesa/swrast/s_fragprog.c   |   12 ++++++++++++
>   src/mesa/swrast/s_fragprog.h   |    2 ++
>   src/mesa/swrast/s_lines.c      |    2 +-
>   src/mesa/swrast/s_span.c       |   38 +++++++++++---------------------------
>   src/mesa/swrast/s_triangle.c   |    4 ++--
>   9 files changed, 45 insertions(+), 44 deletions(-)
>
> diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c
> index d4b1805..d36d876 100644
> --- a/src/mesa/swrast/s_aaline.c
> +++ b/src/mesa/swrast/s_aaline.c
> @@ -479,7 +479,7 @@ _swrast_choose_aa_line_function(struct gl_context *ctx)
>      ASSERT(ctx->Line.SmoothFlag);
>
>      if (ctx->Texture._EnabledCoordUnits != 0
> -       || ctx->FragmentProgram._Current
> +       || _swrast_use_fragment_program(ctx)
>          || (ctx->Light.Enabled&&
>              ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
>          || ctx->Fog.ColorSumEnabled
> diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h
> index 376ef32..ba9f8ab 100644
> --- a/src/mesa/swrast/s_aalinetemp.h
> +++ b/src/mesa/swrast/s_aalinetemp.h
> @@ -67,7 +67,7 @@ NAME(plot)(struct gl_context *ctx, struct LineInfo *line, int ix, int iy)
>      ATTRIB_LOOP_BEGIN
>         GLfloat (*attribArray)[4] = line->span.array->attribs[attr];
>         if (attr>= FRAG_ATTRIB_TEX0&&  attr<  FRAG_ATTRIB_VAR0
> -&&  !ctx->FragmentProgram._Current) {
> +&&  !_swrast_use_fragment_program(ctx)) {
>            /* texcoord w/ divide by Q */
>            const GLuint unit = attr - FRAG_ATTRIB_TEX0;
>            const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]);
> diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c
> index c68fdf6..b59177f 100644
> --- a/src/mesa/swrast/s_aatriangle.c
> +++ b/src/mesa/swrast/s_aatriangle.c
> @@ -299,7 +299,7 @@ _swrast_set_aa_triangle_function(struct gl_context *ctx)
>      ASSERT(ctx->Polygon.SmoothFlag);
>
>      if (ctx->Texture._EnabledCoordUnits != 0
> -       || ctx->FragmentProgram._Current
> +       || _swrast_use_fragment_program(ctx)
>          || swrast->_FogEnabled
>          || _mesa_need_secondary_color(ctx)) {
>         SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri;
> diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
> index 14cb9b1..cc304d7 100644
> --- a/src/mesa/swrast/s_context.c
> +++ b/src/mesa/swrast/s_context.c
> @@ -105,7 +105,7 @@ _swrast_update_rasterflags( struct gl_context *ctx )
>      }
>
>
> -   if (ctx->FragmentProgram._Current) {
> +   if (_swrast_use_fragment_program(ctx)) {
>         rasterMask |= FRAGPROG_BIT;
>      }
>
> @@ -170,7 +170,7 @@ _swrast_update_fog_hint( struct gl_context *ctx )
>   {
>      SWcontext *swrast = SWRAST_CONTEXT(ctx);
>      swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
> -                              ctx->FragmentProgram._Current ||
> +			      _swrast_use_fragment_program(ctx) ||
>   			      (ctx->Hint.Fog == GL_NICEST&&
>   			swrast->AllowPixelFog));
>   }
> @@ -220,13 +220,14 @@ _swrast_update_deferred_texture(struct gl_context *ctx)
>         swrast->_DeferredTexture = GL_FALSE;
>      }
>      else {
> +      GLboolean use_fprog = _swrast_use_fragment_program(ctx);
>         const struct gl_fragment_program *fprog
>            = ctx->FragmentProgram._Current;
> -      if (fprog&&  (fprog->Base.OutputsWritten&  (1<<  FRAG_RESULT_DEPTH))) {
> +      if (use_fprog&&  (fprog->Base.OutputsWritten&  (1<<  FRAG_RESULT_DEPTH))) {
>            /* Z comes from fragment program/shader */
>            swrast->_DeferredTexture = GL_FALSE;
>         }
> -      else if (fprog&&  fprog->UsesKill) {
> +      else if (use_fprog&&  fprog->UsesKill) {
>            swrast->_DeferredTexture = GL_FALSE;
>         }
>         else if (ctx->Query.CurrentOcclusionObject) {
> @@ -254,7 +255,8 @@ _swrast_update_fog_state( struct gl_context *ctx )
>             (fp->Base.Target == GL_FRAGMENT_PROGRAM_NV));
>
>      /* determine if fog is needed, and if so, which fog mode */
> -   swrast->_FogEnabled = (fp == NULL&&  ctx->Fog.Enabled);
> +   swrast->_FogEnabled = (!_swrast_use_fragment_program(ctx)&&
> +			  ctx->Fog.Enabled);
>   }
>
>
> @@ -265,10 +267,11 @@ _swrast_update_fog_state( struct gl_context *ctx )
>   static void
>   _swrast_update_fragment_program(struct gl_context *ctx, GLbitfield newState)
>   {
> -   const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
> -   if (fp) {
> -      _mesa_load_state_parameters(ctx, fp->Base.Parameters);
> -   }
> +   if (!_swrast_use_fragment_program(ctx))
> +      return;
> +
> +   _mesa_load_state_parameters(ctx,
> +                               ctx->FragmentProgram._Current->Base.Parameters);
>   }
>
>
> @@ -286,7 +289,7 @@ _swrast_update_specular_vertex_add(struct gl_context *ctx)
>
>      swrast->SpecularVertexAdd = (separateSpecular
>                                   &&  ctx->Texture._EnabledUnits == 0x0
> -&&  !ctx->FragmentProgram._Current
> +&&  !_swrast_use_fragment_program(ctx)
>                                   &&  !ctx->ATIFragmentShader._Enabled);
>   }
>
> @@ -497,7 +500,7 @@ _swrast_update_active_attribs(struct gl_context *ctx)
>      /*
>       * Compute _ActiveAttribsMask = which fragment attributes are needed.
>       */
> -   if (ctx->FragmentProgram._Current) {
> +   if (_swrast_use_fragment_program(ctx)) {
>         /* fragment program/shader */
>         attribsMask = ctx->FragmentProgram._Current->Base.InputsRead;
>         attribsMask&= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */
> diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
> index 1caa0eb..a2ff27c 100644
> --- a/src/mesa/swrast/s_fragprog.c
> +++ b/src/mesa/swrast/s_fragprog.c
> @@ -30,6 +30,18 @@
>   #include "s_fragprog.h"
>   #include "s_span.h"
>
> +/**
> + * \brief Should swrast use a fragment program?
> + *
> + * \return true if the current fragment program is not the fixed function
> + *         fragment program
> + */
> +GLboolean
> +_swrast_use_fragment_program(struct gl_context *ctx)
> +{
> +   struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
> +   return fp&&  fp != ctx->FragmentProgram._TexEnvProgram;
> +}
>
>   /**
>    * Apply texture object's swizzle (X/Y/Z/W/0/1) to incoming 'texel'
> diff --git a/src/mesa/swrast/s_fragprog.h b/src/mesa/swrast/s_fragprog.h
> index 62a6836..ac1f5ff 100644
> --- a/src/mesa/swrast/s_fragprog.h
> +++ b/src/mesa/swrast/s_fragprog.h
> @@ -31,6 +31,8 @@
>
>   struct gl_context;
>
> +GLboolean
> +_swrast_use_fragment_program(struct gl_context *ctx);
>
>   extern void
>   _swrast_exec_fragment_program(struct gl_context *ctx, SWspan *span);
> diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c
> index 95a2a5d..ee997b0 100644
> --- a/src/mesa/swrast/s_lines.c
> +++ b/src/mesa/swrast/s_lines.c
> @@ -236,7 +236,7 @@ _swrast_choose_line( struct gl_context *ctx )
>            ASSERT(swrast->Line);
>         }
>         else if (ctx->Texture._EnabledCoordUnits
> -               || ctx->FragmentProgram._Current
> +               || _swrast_use_fragment_program(ctx)
>                  || swrast->_FogEnabled
>                  || specular) {
>            USE(general_line);
> diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
> index ccdbe5f..28f2f3d 100644
> --- a/src/mesa/swrast/s_span.c
> +++ b/src/mesa/swrast/s_span.c
> @@ -139,7 +139,8 @@ _swrast_span_default_attribs(struct gl_context *ctx, SWspan *span)
>         for (i = 0; i<  ctx->Const.MaxTextureCoordUnits; i++) {
>            const GLuint attr = FRAG_ATTRIB_TEX0 + i;
>            const GLfloat *tc = ctx->Current.RasterTexCoords[i];
> -         if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) {
> +         if (_swrast_use_fragment_program(ctx) ||
> +             ctx->ATIFragmentShader._Enabled) {
>               COPY_4V(span->attrStart[attr], tc);
>            }
>            else if (tc[3]>  0.0F) {
> @@ -498,7 +499,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
>                  swrast_texture_image_const(img);
>
>               needLambda = (obj->Sampler.MinFilter != obj->Sampler.MagFilter)
> -               || ctx->FragmentProgram._Current;
> +               || _swrast_use_fragment_program(ctx);
>               /* LOD is calculated directly in the ansiotropic filter, we can
>                * skip the normal lambda function as the result is ignored.
>                */
> @@ -518,7 +519,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
>
>            if (needLambda) {
>               GLuint i;
> -            if (ctx->FragmentProgram._Current
> +            if (_swrast_use_fragment_program(ctx)
>                   || ctx->ATIFragmentShader._Enabled) {
>                  /* do perspective correction but don't divide s, t, r by q */
>                  const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
> @@ -559,7 +560,7 @@ interpolate_texcoords(struct gl_context *ctx, SWspan *span)
>            }
>            else {
>               GLuint i;
> -            if (ctx->FragmentProgram._Current ||
> +            if (_swrast_use_fragment_program(ctx) ||
>                   ctx->ATIFragmentShader._Enabled) {
>                  /* do perspective correction but don't divide s, t, r by q */
>                  const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3];
> @@ -833,7 +834,7 @@ add_specular(struct gl_context *ctx, SWspan *span)
>      GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1];
>      GLuint i;
>
> -   ASSERT(!ctx->FragmentProgram._Current);
> +   ASSERT(!_swrast_use_fragment_program(ctx));
>      ASSERT(span->arrayMask&  SPAN_RGBA);
>      ASSERT(swrast->_ActiveAttribMask&  FRAG_BIT_COL1);
>      (void) swrast; /* silence warning */
> @@ -971,25 +972,7 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output)
>   static inline void
>   shade_texture_span(struct gl_context *ctx, SWspan *span)
>   {
> -   /* This is a hack to work around drivers such as i965 that:
> -    *
> -    *     - Set _MaintainTexEnvProgram to generate GLSL IR for
> -    *       fixed-function fragment processing.
> -    *     - Don't call _mesa_ir_link_shader to generate Mesa IR from
> -    *       the GLSL IR.
> -    *     - May use swrast to handle glDrawPixels.
> -    *
> -    * Since _mesa_ir_link_shader is never called, there is no Mesa IR
> -    * to execute.  Instead do regular fixed-function processing.
> -    *
> -    * It is also worth noting that the software fixed-function path is
> -    * much faster than the software shader path.
> -    */
> -   const bool use_fragment_program =
> -      ctx->FragmentProgram._Current
> -&&  ctx->FragmentProgram._Current != ctx->FragmentProgram._TexEnvProgram;
> -
> -   if (use_fragment_program ||
> +   if (_swrast_use_fragment_program(ctx) ||
>          ctx->ATIFragmentShader._Enabled) {
>         /* programmable shading */
>         if (span->primitive == GL_BITMAP&&  span->array->ChanType != GL_FLOAT) {
> @@ -1018,7 +1001,7 @@ shade_texture_span(struct gl_context *ctx, SWspan *span)
>            interpolate_wpos(ctx, span);
>
>         /* Run fragment program/shader now */
> -      if (use_fragment_program) {
> +      if (_swrast_use_fragment_program(ctx)) {
>            _swrast_exec_fragment_program(ctx, span);
>         }
>         else {
> @@ -1151,7 +1134,7 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
>      const GLbitfield64 origArrayAttribs = span->arrayAttribs;
>      const GLenum origChanType = span->array->ChanType;
>      void * const origRgba = span->array->rgba;
> -   const GLboolean shader = (ctx->FragmentProgram._Current
> +   const GLboolean shader = (_swrast_use_fragment_program(ctx)
>                                || ctx->ATIFragmentShader._Enabled);
>      const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledCoordUnits;
>      struct gl_framebuffer *fb = ctx->DrawBuffer;
> @@ -1326,7 +1309,8 @@ _swrast_write_rgba_span( struct gl_context *ctx, SWspan *span)
>         const GLuint numBuffers = fb->_NumColorDrawBuffers;
>         const struct gl_fragment_program *fp = ctx->FragmentProgram._Current;
>         const GLboolean multiFragOutputs =
> -         (fp&&  fp->Base.OutputsWritten>= (1<<  FRAG_RESULT_DATA0));
> +         _swrast_use_fragment_program(ctx)
> +&&  fp->Base.OutputsWritten>= (1<<  FRAG_RESULT_DATA0);
>         GLuint buf;
>
>         for (buf = 0; buf<  numBuffers; buf++) {
> diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c
> index 124aa5f..ddb4792 100644
> --- a/src/mesa/swrast/s_triangle.c
> +++ b/src/mesa/swrast/s_triangle.c
> @@ -1038,7 +1038,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
>          * needs to be interpolated.
>          */
>         if (ctx->Texture._EnabledCoordUnits ||
> -          ctx->FragmentProgram._Current ||
> +	  _swrast_use_fragment_program(ctx) ||
>             ctx->ATIFragmentShader._Enabled ||
>             _mesa_need_secondary_color(ctx) ||
>             swrast->_FogEnabled) {
> @@ -1060,7 +1060,7 @@ _swrast_choose_triangle( struct gl_context *ctx )
>
>            /* First see if we can use an optimized 2-D texture function */
>            if (ctx->Texture._EnabledCoordUnits == 0x1
> -&&  !ctx->FragmentProgram._Current
> +&&  !_swrast_use_fragment_program(ctx)
>                &&  !ctx->ATIFragmentShader._Enabled
>                &&  ctx->Texture._EnabledUnits == 0x1
>                &&  ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT



More information about the mesa-dev mailing list