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<i...@freedesktop.org>

Reviewed-by: Ian Romanick <ian.d.roman...@intel.com>

CC: Eric Anholt<e...@anholt.net>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=43327
Signed-off-by: Chad Versace<chad.vers...@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

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to