[Mesa-dev] [PATCH 1/2] draw: simplify (and correct) aaline fallback (v2)

Brian Paul brianp at vmware.com
Tue Mar 6 20:52:53 UTC 2018


Looks good.  That certainly does simplify things.  Two minor suggestions 
below.

In any case, for both, Reviewed-by: Brian Paul <brianp at vmware.com>

On 03/06/2018 01:34 PM, sroland at vmware.com wrote:
> From: Roland Scheidegger <sroland at vmware.com>
> 
> The motivation actually was to get rid of the additional tex
> instruction, since that requires the draw fallback code to intercept
> all sampler / view calls (even if the fallback is never hit).
> Basically, the idea is to use coverage of the pixel to calculate
> the alpha value, and coverage is simply based on the distance
> to the center of the line (in both line direction, which is useful
> for wide lines, as well as perpendicular to the line).
> This is much closer to what hw supporting this natively actually does.
> It also fixes an issue with line width not quite being correct, as
> well as endpoints getting stretched too far (in line direction) with
> wide lines, which is apparent with mesa demo line-width.
> (For llvmpipe, it would probably make sense to do something like this
> directly when drawing lines, since rendering two tris is twice as
> expensive as a line, but it would need some changes with state
> management.)
> Since we're no longer relying on mipmapping to get the alpha value,
> we also don't need to draw 3 rects (6 tris), one is sufficient.
> 
> There's still issues (as before):
> - quite sure it's not correct without half_pixel_center, but can't test
> this with GL.
> - aaline + line stipple is incorrect (evident with line-width demo).
> Looking at the spec the stipple pattern should actually be based on
> distance (not just dx or dy for x/y major lines as without aa).
> - outputs (other than pos + the one used for line aa) should be
> reinterpolated since we actually increase line length by half a pixel
> (but there's no tests which would care).
> 
> v2: simplify the math (should be equivalent), don't need immediate
> ---
>   src/gallium/auxiliary/draw/draw_pipe_aaline.c | 504 +++++---------------------
>   1 file changed, 100 insertions(+), 404 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> index a859dbc..591e2a3 100644
> --- a/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> +++ b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
> @@ -1,6 +1,6 @@
>   /**************************************************************************
>    *
> - * Copyright 2007 VMware, Inc.
> + * Copyright 2007-2018 VMware, Inc.
>    * All Rights Reserved.
>    *
>    * Permission is hereby granted, free of charge, to any person obtaining a
> @@ -26,7 +26,7 @@
>    **************************************************************************/
>   
>   /**
> - * AA line stage:  AA lines are converted to texture mapped triangles.
> + * AA line stage:  AA lines are converted triangles (with extra generic)
>    *
>    * Authors:  Brian Paul
>    */
> @@ -40,7 +40,6 @@
>   #include "util/u_format.h"
>   #include "util/u_math.h"
>   #include "util/u_memory.h"
> -#include "util/u_sampler.h"
>   
>   #include "tgsi/tgsi_transform.h"
>   #include "tgsi/tgsi_dump.h"
> @@ -55,19 +54,6 @@
>   
>   
>   /**
> - * Size for the alpha texture used for antialiasing
> - */
> -#define TEXTURE_SIZE_LOG2  5   /* 32 x 32 */
> -
> -/**
> - * Max texture level for the alpha texture used for antialiasing
> - *
> - * Don't use the 1x1 and 2x2 mipmap levels.
> - */
> -#define MAX_TEXTURE_LEVEL  (TEXTURE_SIZE_LOG2 - 2)
> -
> -
> -/**
>    * Subclass of pipe_shader_state to carry extra fragment shader info.
>    */
>   struct aaline_fragment_shader
> @@ -75,8 +61,7 @@ struct aaline_fragment_shader
>      struct pipe_shader_state state;
>      void *driver_fs;
>      void *aaline_fs;
> -   uint sampler_unit;
> -   int generic_attrib;  /**< texcoord/generic used for texture */
> +   int generic_attrib;  /**< generic used for distance */
>   };
>   
>   
> @@ -89,26 +74,16 @@ struct aaline_stage
>   
>      float half_line_width;
>   
> -   /** For AA lines, this is the vertex attrib slot for the new texcoords */
> -   uint tex_slot;
> +   /** For AA lines, this is the vertex attrib slot for new generic */
> +   uint coord_slot;
>      /** position, not necessarily output zero */
>      uint pos_slot;
>   
> -   void *sampler_cso;
> -   struct pipe_resource *texture;
> -   struct pipe_sampler_view *sampler_view;
> -   uint num_samplers;
> -   uint num_sampler_views;
> -
>   
>      /*
>       * Currently bound state
>       */
>      struct aaline_fragment_shader *fs;
> -   struct {
> -      void *sampler[PIPE_MAX_SAMPLERS];
> -      struct pipe_sampler_view *sampler_views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
> -   } state;
>   
>      /*
>       * Driver interface/override functions
> @@ -117,15 +92,6 @@ struct aaline_stage
>                                       const struct pipe_shader_state *);
>      void (*driver_bind_fs_state)(struct pipe_context *, void *);
>      void (*driver_delete_fs_state)(struct pipe_context *, void *);
> -
> -   void (*driver_bind_sampler_states)(struct pipe_context *,
> -                                      enum pipe_shader_type, unsigned,
> -                                      unsigned, void **);
> -
> -   void (*driver_set_sampler_views)(struct pipe_context *,
> -                                    enum pipe_shader_type shader,
> -                                    unsigned start, unsigned count,
> -                                    struct pipe_sampler_view **);
>   };
>   
>   
> @@ -136,41 +102,27 @@ struct aaline_stage
>    */
>   struct aa_transform_context {
>      struct tgsi_transform_context base;
> -   uint tempsUsed;  /**< bitmask */
> +   uint64_t tempsUsed;  /**< bitmask */
>      int colorOutput; /**< which output is the primary color */
> -   uint samplersUsed;  /**< bitfield of samplers used */
> -   bool hasSview;
> -   int freeSampler;  /** an available sampler for the pstipple */
>      int maxInput, maxGeneric;  /**< max input index found */
> -   int colorTemp, texTemp;  /**< temp registers */
> +   int colorTemp, aaTemp;  /**< temp registers */
>   };
>   
> -
>   /**
>    * TGSI declaration transform callback.
> - * Look for a free sampler, a free input attrib, and two free temp regs.
> + * Look for a free input attrib, and two free temp regs.
>    */
>   static void
>   aa_transform_decl(struct tgsi_transform_context *ctx,
>                     struct tgsi_full_declaration *decl)
>   {
> -   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
> +   struct aa_transform_context *aactx = (struct aa_transform_context *)ctx;
>   
>      if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
>          decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
>          decl->Semantic.Index == 0) {
>         aactx->colorOutput = decl->Range.First;
>      }
> -   else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
> -      uint i;
> -      for (i = decl->Range.First;
> -           i <= decl->Range.Last; i++) {
> -         aactx->samplersUsed |= 1u << i;
> -      }
> -   }
> -   else if (decl->Declaration.File == TGSI_FILE_SAMPLER_VIEW) {
> -      aactx->hasSview = true;
> -   }
>      else if (decl->Declaration.File == TGSI_FILE_INPUT) {
>         if ((int) decl->Range.Last > aactx->maxInput)
>            aactx->maxInput = decl->Range.Last;
> @@ -183,7 +135,10 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
>         uint i;
>         for (i = decl->Range.First;
>              i <= decl->Range.Last; i++) {
> -         aactx->tempsUsed |= (1 << i);
> +         /*
> +          * XXX this bitfield doesn't cut it...
> +          */
> +         aactx->tempsUsed |= (1ULL << i);
>         }
>      }
>   
> @@ -192,16 +147,6 @@ aa_transform_decl(struct tgsi_transform_context *ctx,
>   
>   
>   /**
> - * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
> - */
> -static int
> -free_bit(uint bitfield)
> -{
> -   return ffs(~bitfield) - 1;
> -}
> -
> -
> -/**
>    * TGSI transform prolog callback.
>    */
>   static void
> @@ -210,49 +155,29 @@ aa_transform_prolog(struct tgsi_transform_context *ctx)
>      struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
>      uint i;
>   
> -   STATIC_ASSERT(sizeof(aactx->samplersUsed) * 8 >= PIPE_MAX_SAMPLERS);
> -
> -   /* find free sampler */
> -   aactx->freeSampler = free_bit(aactx->samplersUsed);
> -   if (aactx->freeSampler < 0 || aactx->freeSampler >= PIPE_MAX_SAMPLERS)
> -      aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
>   
>      /* find two free temp regs */
> -   for (i = 0; i < 32; i++) {
> +   for (i = 0; i < 64; i++) {
>         if ((aactx->tempsUsed & (1 << i)) == 0) {
>         /* found a free temp */
>         if (aactx->colorTemp < 0)
>            aactx->colorTemp  = i;
> -      else if (aactx->texTemp < 0)
> -         aactx->texTemp  = i;
> +      else if (aactx->aaTemp < 0)
> +         aactx->aaTemp  = i;
>         else
>            break;
>         }
>      }

The loop could probably be eliminated and replaced with a couple 
ffsll(~tempsUsed) calls.


>      assert(aactx->colorTemp >= 0);
> -   assert(aactx->texTemp >= 0);
> +   assert(aactx->aaTemp >= 0);
>   
>      /* declare new generic input/texcoord */
>      tgsi_transform_input_decl(ctx, aactx->maxInput + 1,
>                                TGSI_SEMANTIC_GENERIC, aactx->maxGeneric + 1,
>                                TGSI_INTERPOLATE_LINEAR);
>   
> -   /* declare new sampler */
> -   tgsi_transform_sampler_decl(ctx, aactx->freeSampler);
> -
> -   /* if the src shader has SVIEW decl's for each SAMP decl, we
> -    * need to continue the trend and ensure there is a matching
> -    * SVIEW for the new SAMP we just created
> -    */
> -   if (aactx->hasSview) {
> -      tgsi_transform_sampler_view_decl(ctx,
> -                                       aactx->freeSampler,
> -                                       TGSI_TEXTURE_2D,
> -                                       TGSI_RETURN_TYPE_FLOAT);
> -   }
> -
>      /* declare new temp regs */
> -   tgsi_transform_temp_decl(ctx, aactx->texTemp);
> +   tgsi_transform_temp_decl(ctx, aactx->aaTemp);
>      tgsi_transform_temp_decl(ctx, aactx->colorTemp);
>   }
>   
> @@ -266,13 +191,41 @@ aa_transform_epilog(struct tgsi_transform_context *ctx)
>      struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
>   
>      if (aactx->colorOutput != -1) {
> -      /* insert texture sampling code for antialiasing. */
> -
> -      /* TEX texTemp, input_coord, sampler, 2D */
> -      tgsi_transform_tex_inst(ctx,
> -                              TGSI_FILE_TEMPORARY, aactx->texTemp,
> -                              TGSI_FILE_INPUT, aactx->maxInput + 1,
> -                              TGSI_TEXTURE_2D, aactx->freeSampler);
> +      struct tgsi_full_instruction inst;
> +      /* insert distance-based coverage code for antialiasing. */
> +
> +      /* saturate(linewidth - fabs(interpx), linelength - fabs(interpz) */
> +      inst = tgsi_default_full_instruction();
> +      inst.Instruction.Saturate = true;
> +      inst.Instruction.Opcode = TGSI_OPCODE_ADD;
> +      inst.Instruction.NumDstRegs = 1;
> +      tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
> +                             aactx->aaTemp, TGSI_WRITEMASK_XZ);
> +      inst.Instruction.NumSrcRegs = 2;
> +      tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_INPUT, aactx->maxInput + 1,
> +                             TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
> +                             TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
> +      tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_INPUT, aactx->maxInput + 1,
> +                             TGSI_SWIZZLE_Y, TGSI_SWIZZLE_Y,
> +                             TGSI_SWIZZLE_W, TGSI_SWIZZLE_W);
> +      inst.Src[1].Register.Absolute = true;
> +      inst.Src[1].Register.Negate = true;
> +      ctx->emit_instruction(ctx, &inst);
> +
> +      /* MUL width / height alpha */
> +      inst = tgsi_default_full_instruction();
> +      inst.Instruction.Opcode = TGSI_OPCODE_MUL;
> +      inst.Instruction.NumDstRegs = 1;
> +      tgsi_transform_dst_reg(&inst.Dst[0], TGSI_FILE_TEMPORARY,
> +                             aactx->aaTemp, TGSI_WRITEMASK_W);
> +      inst.Instruction.NumSrcRegs = 2;
> +      tgsi_transform_src_reg(&inst.Src[0], TGSI_FILE_TEMPORARY, aactx->aaTemp,
> +                             TGSI_SWIZZLE_X, TGSI_SWIZZLE_X,
> +                             TGSI_SWIZZLE_X, TGSI_SWIZZLE_X);
> +      tgsi_transform_src_reg(&inst.Src[1], TGSI_FILE_TEMPORARY, aactx->aaTemp,
> +                             TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z,
> +                             TGSI_SWIZZLE_Z, TGSI_SWIZZLE_Z);
> +      ctx->emit_instruction(ctx, &inst);

I think you might be able to use tgsi_transform_op2_swz_inst() here.


>   
>         /* MOV rgb */
>         tgsi_transform_op1_inst(ctx, TGSI_OPCODE_MOV,
> @@ -285,7 +238,7 @@ aa_transform_epilog(struct tgsi_transform_context *ctx)
>                                 TGSI_FILE_OUTPUT, aactx->colorOutput,
>                                 TGSI_WRITEMASK_W,
>                                 TGSI_FILE_TEMPORARY, aactx->colorTemp,
> -                              TGSI_FILE_TEMPORARY, aactx->texTemp, false);
> +                              TGSI_FILE_TEMPORARY, aactx->aaTemp, false);
>      }
>   }
>   
> @@ -319,7 +272,7 @@ aa_transform_inst(struct tgsi_transform_context *ctx,
>   
>   /**
>    * Generate the frag shader we'll use for drawing AA lines.
> - * This will be the user's shader plus some texture/modulate instructions.
> + * This will be the user's shader plus some arithmetic instructions.
>    */
>   static boolean
>   generate_aaline_fs(struct aaline_stage *aaline)
> @@ -340,7 +293,7 @@ generate_aaline_fs(struct aaline_stage *aaline)
>      transform.maxInput = -1;
>      transform.maxGeneric = -1;
>      transform.colorTemp = -1;
> -   transform.texTemp = -1;
> +   transform.aaTemp = -1;
>      transform.base.prolog = aa_transform_prolog;
>      transform.base.epilog = aa_transform_epilog;
>      transform.base.transform_instruction = aa_transform_inst;
> @@ -357,8 +310,6 @@ generate_aaline_fs(struct aaline_stage *aaline)
>      tgsi_dump(aaline_fs.tokens, 0);
>   #endif
>   
> -   aaline->fs->sampler_unit = transform.freeSampler;
> -
>      aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs);
>      if (aaline->fs->aaline_fs == NULL)
>         goto fail;
> @@ -374,125 +325,6 @@ fail:
>   
>   
>   /**
> - * Create the texture map we'll use for antialiasing the lines.
> - */
> -static boolean
> -aaline_create_texture(struct aaline_stage *aaline)
> -{
> -   struct pipe_context *pipe = aaline->stage.draw->pipe;
> -   struct pipe_screen *screen = pipe->screen;
> -   struct pipe_resource texTemp;
> -   struct pipe_sampler_view viewTempl;
> -   uint level;
> -
> -   memset(&texTemp, 0, sizeof(texTemp));
> -   texTemp.target = PIPE_TEXTURE_2D;
> -   texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
> -   texTemp.last_level = MAX_TEXTURE_LEVEL;
> -   texTemp.width0 = 1 << TEXTURE_SIZE_LOG2;
> -   texTemp.height0 = 1 << TEXTURE_SIZE_LOG2;
> -   texTemp.depth0 = 1;
> -   texTemp.array_size = 1;
> -   texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
> -
> -   aaline->texture = screen->resource_create(screen, &texTemp);
> -   if (!aaline->texture)
> -      return FALSE;
> -
> -   u_sampler_view_default_template(&viewTempl,
> -                                   aaline->texture,
> -                                   aaline->texture->format);
> -   aaline->sampler_view = pipe->create_sampler_view(pipe,
> -                                                    aaline->texture,
> -                                                    &viewTempl);
> -   if (!aaline->sampler_view) {
> -      return FALSE;
> -   }
> -
> -   /* Fill in mipmap images.
> -    * Basically each level is solid opaque, except for the outermost
> -    * texels which are zero.  Special case the 1x1 and 2x2 levels
> -    * (though, those levels shouldn't be used - see the max_lod setting).
> -    */
> -   for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
> -      struct pipe_transfer *transfer;
> -      struct pipe_box box;
> -      const uint size = u_minify(aaline->texture->width0, level);
> -      ubyte *data;
> -      uint i, j;
> -
> -      assert(aaline->texture->width0 == aaline->texture->height0);
> -
> -      u_box_origin_2d(size, size, &box);
> -
> -      /* This texture is new, no need to flush.
> -       */
> -      data = pipe->transfer_map(pipe,
> -                                aaline->texture,
> -                                level,
> -                                PIPE_TRANSFER_WRITE,
> -                                &box, &transfer);
> -
> -      if (!data)
> -         return FALSE;
> -
> -      for (i = 0; i < size; i++) {
> -         for (j = 0; j < size; j++) {
> -            ubyte d;
> -            if (size == 1) {
> -               d = 255;
> -            }
> -            else if (size == 2) {
> -               d = 200; /* tuneable */
> -            }
> -            else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) {
> -               d = 35;  /* edge texel */
> -            }
> -            else {
> -               d = 255;
> -            }
> -            data[i * transfer->stride + j] = d;
> -         }
> -      }
> -
> -      /* unmap */
> -      pipe->transfer_unmap(pipe, transfer);
> -   }
> -   return TRUE;
> -}
> -
> -
> -/**
> - * Create the sampler CSO that'll be used for antialiasing.
> - * By using a mipmapped texture, we don't have to generate a different
> - * texture image for each line size.
> - */
> -static boolean
> -aaline_create_sampler(struct aaline_stage *aaline)
> -{
> -   struct pipe_sampler_state sampler;
> -   struct pipe_context *pipe = aaline->stage.draw->pipe;
> -
> -   memset(&sampler, 0, sizeof(sampler));
> -   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
> -   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
> -   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
> -   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
> -   sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
> -   sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
> -   sampler.normalized_coords = 1;
> -   sampler.min_lod = 0.0f;
> -   sampler.max_lod = MAX_TEXTURE_LEVEL;
> -
> -   aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
> -   if (aaline->sampler_cso == NULL)
> -      return FALSE;
> -
> -   return TRUE;
> -}
> -
> -
> -/**
>    * When we're about to draw our first AA line in a batch, this function is
>    * called to tell the driver to bind our modified fragment shader.
>    */
> @@ -532,112 +364,83 @@ aaline_line(struct draw_stage *stage, struct prim_header *header)
>      const float half_width = aaline->half_line_width;
>      struct prim_header tri;
>      struct vertex_header *v[8];
> -   uint texPos = aaline->tex_slot;
> +   uint coordPos = aaline->coord_slot;
>      uint posPos = aaline->pos_slot;
>      float *pos, *tex;
>      float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0];
>      float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1];
>      double a = atan2(dy, dx);
>      float c_a = (float) cos(a), s_a = (float) sin(a);
> +   float half_length;
> +   float t_l, t_w;
>      uint i;
>   
> -   /* XXX the ends of lines aren't quite perfect yet, but probably passable */
> -   dx = 0.5F * half_width;
> -   dy = half_width;
> +   half_length = sqrtf(dx * dx + dy * dy) / 2.0f + 0.5f;
> +
> +   t_w = half_width;
> +   t_l = 0.5f;
>   
>      /* allocate/dup new verts */
> -   for (i = 0; i < 8; i++) {
> -      v[i] = dup_vert(stage, header->v[i/4], i);
> +   for (i = 0; i < 4; i++) {
> +      v[i] = dup_vert(stage, header->v[i/2], i);
>      }
>   
>      /*
>       * Quad strip for line from v0 to v1 (*=endpoints):
>       *
> -    *  1   3                     5   7
> -    *  +---+---------------------+---+
> +    *  1                             3
> +    *  +-----------------------------+
>       *  |                             |
>       *  | *v0                     v1* |
>       *  |                             |
> -    *  +---+---------------------+---+
> -    *  0   2                     4   6
> +    *  +-----------------------------+
> +    *  0                             2
> +    */
> +
> +   /*
> +    * We increase line length by 0.5 pixels (at each endpoint),
> +    * and calculate the tri endpoints by moving them half-width
> +    * distance away perpendicular to the line.
> +    * XXX: since we change line endpoints (by 0.5 pixel), should
> +    * actually re-interpolate all other values?
>       */
>   
>      /* new verts */
>      pos = v[0]->data[posPos];
> -   pos[0] += (-dx * c_a -  dy * s_a);
> -   pos[1] += (-dx * s_a +  dy * c_a);
> +   pos[0] += (-t_l * c_a -  t_w * s_a);
> +   pos[1] += (-t_l * s_a +  t_w * c_a);
>   
>      pos = v[1]->data[posPos];
> -   pos[0] += (-dx * c_a - -dy * s_a);
> -   pos[1] += (-dx * s_a + -dy * c_a);
> +   pos[0] += (-t_l * c_a - -t_w * s_a);
> +   pos[1] += (-t_l * s_a + -t_w * c_a);
>   
>      pos = v[2]->data[posPos];
> -   pos[0] += (dx * c_a -  dy * s_a);
> -   pos[1] += (dx * s_a +  dy * c_a);
> +   pos[0] += (t_l * c_a -  t_w * s_a);
> +   pos[1] += (t_l * s_a +  t_w * c_a);
>   
>      pos = v[3]->data[posPos];
> -   pos[0] += (dx * c_a - -dy * s_a);
> -   pos[1] += (dx * s_a + -dy * c_a);
> -
> -   pos = v[4]->data[posPos];
> -   pos[0] += (-dx * c_a -  dy * s_a);
> -   pos[1] += (-dx * s_a +  dy * c_a);
> -
> -   pos = v[5]->data[posPos];
> -   pos[0] += (-dx * c_a - -dy * s_a);
> -   pos[1] += (-dx * s_a + -dy * c_a);
> -
> -   pos = v[6]->data[posPos];
> -   pos[0] += (dx * c_a -  dy * s_a);
> -   pos[1] += (dx * s_a +  dy * c_a);
> -
> -   pos = v[7]->data[posPos];
> -   pos[0] += (dx * c_a - -dy * s_a);
> -   pos[1] += (dx * s_a + -dy * c_a);
> +   pos[0] += (t_l * c_a - -t_w * s_a);
> +   pos[1] += (t_l * s_a + -t_w * c_a);
>   
>      /* new texcoords */
> -   tex = v[0]->data[texPos];
> -   ASSIGN_4V(tex, 0, 0, 0, 1);
> -
> -   tex = v[1]->data[texPos];
> -   ASSIGN_4V(tex, 0, 1, 0, 1);
> -
> -   tex = v[2]->data[texPos];
> -   ASSIGN_4V(tex, .5, 0, 0, 1);
> +   tex = v[0]->data[coordPos];
> +   /* XXX need to adjust for pixel center? */
> +   ASSIGN_4V(tex, -half_width, half_width, -half_length, half_length);
>   
> -   tex = v[3]->data[texPos];
> -   ASSIGN_4V(tex, .5, 1, 0, 1);
> +   tex = v[1]->data[coordPos];
> +   ASSIGN_4V(tex, half_width, half_width, -half_length, half_length);
>   
> -   tex = v[4]->data[texPos];
> -   ASSIGN_4V(tex, .5, 0, 0, 1);
> +   tex = v[2]->data[coordPos];
> +   ASSIGN_4V(tex, -half_width, half_width, half_length, half_length);
>   
> -   tex = v[5]->data[texPos];
> -   ASSIGN_4V(tex, .5, 1, 0, 1);
> +   tex = v[3]->data[coordPos];
> +   ASSIGN_4V(tex, half_width, half_width, half_length, half_length);
>   
> -   tex = v[6]->data[texPos];
> -   ASSIGN_4V(tex, 1, 0, 0, 1);
> -
> -   tex = v[7]->data[texPos];
> -   ASSIGN_4V(tex, 1, 1, 0, 1);
> -
> -   /* emit 6 tris for the quad strip */
>      tri.v[0] = v[2];  tri.v[1] = v[1];  tri.v[2] = v[0];
>      stage->next->tri(stage->next, &tri);
>   
>      tri.v[0] = v[3];  tri.v[1] = v[1];  tri.v[2] = v[2];
>      stage->next->tri(stage->next, &tri);
> -
> -   tri.v[0] = v[4];  tri.v[1] = v[3];  tri.v[2] = v[2];
> -   stage->next->tri(stage->next, &tri);
> -
> -   tri.v[0] = v[5];  tri.v[1] = v[3];  tri.v[2] = v[4];
> -   stage->next->tri(stage->next, &tri);
> -
> -   tri.v[0] = v[6];  tri.v[1] = v[5];  tri.v[2] = v[4];
> -   stage->next->tri(stage->next, &tri);
> -
> -   tri.v[0] = v[7];  tri.v[1] = v[5];  tri.v[2] = v[6];
> -   stage->next->tri(stage->next, &tri);
>   }
>   
>   
> @@ -648,19 +451,17 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
>      struct draw_context *draw = stage->draw;
>      struct pipe_context *pipe = draw->pipe;
>      const struct pipe_rasterizer_state *rast = draw->rasterizer;
> -   uint num_samplers;
> -   uint num_sampler_views;
>      void *r;
>   
>      assert(draw->rasterizer->line_smooth);
>   
> -   if (draw->rasterizer->line_width <= 2.2)
> -      aaline->half_line_width = 1.1f;
> +   if (draw->rasterizer->line_width <= 1.0)
> +      aaline->half_line_width = 1.0;
>      else
> -      aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
> +      aaline->half_line_width = 0.5f * draw->rasterizer->line_width + 0.5f;
>   
>      /*
> -    * Bind (generate) our fragprog, sampler and texture
> +    * Bind (generate) our fragprog
>       */
>      if (!bind_aaline_fragment_shader(aaline)) {
>         stage->line = draw_pipe_passthrough_line;
> @@ -670,23 +471,8 @@ aaline_first_line(struct draw_stage *stage, struct prim_header *header)
>   
>      draw_aaline_prepare_outputs(draw, draw->pipeline.aaline);
>   
> -   /* how many samplers? */
> -   /* we'll use sampler/texture[aaline->sampler_unit] for the alpha texture */
> -   num_samplers = MAX2(aaline->num_samplers, aaline->fs->sampler_unit + 1);
> -   num_sampler_views = MAX2(num_samplers, aaline->num_sampler_views);
> -
> -   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
> -   pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
> -                               aaline->sampler_view);
> -
>      draw->suspend_flushing = TRUE;
>   
> -   aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
> -                                      num_samplers, aaline->state.sampler);
> -
> -   aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
> -                                    num_sampler_views, aaline->state.sampler_views);
> -
>      /* Disable triangle culling, stippling, unfilled mode etc. */
>      r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
>      pipe->bind_rasterizer_state(pipe, r);
> @@ -709,18 +495,10 @@ aaline_flush(struct draw_stage *stage, unsigned flags)
>      stage->line = aaline_first_line;
>      stage->next->flush(stage->next, flags);
>   
> -   /* restore original frag shader, texture, sampler state */
> +   /* restore original frag shader */
>      draw->suspend_flushing = TRUE;
>      aaline->driver_bind_fs_state(pipe, aaline->fs ? aaline->fs->driver_fs : NULL);
>   
> -   aaline->driver_bind_sampler_states(pipe, PIPE_SHADER_FRAGMENT, 0,
> -                                      aaline->num_samplers,
> -                                      aaline->state.sampler);
> -
> -   aaline->driver_set_sampler_views(pipe, PIPE_SHADER_FRAGMENT, 0,
> -                                    aaline->num_samplers,
> -                                    aaline->state.sampler_views);
> -
>      /* restore original rasterizer state */
>      if (draw->rast_handle) {
>         pipe->bind_rasterizer_state(pipe, draw->rast_handle);
> @@ -744,21 +522,6 @@ aaline_destroy(struct draw_stage *stage)
>   {
>      struct aaline_stage *aaline = aaline_stage(stage);
>      struct pipe_context *pipe = stage->draw->pipe;
> -   uint i;
> -
> -   for (i = 0; i < PIPE_MAX_SHADER_SAMPLER_VIEWS; i++) {
> -      pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
> -   }
> -
> -   if (aaline->sampler_cso)
> -      pipe->delete_sampler_state(pipe, aaline->sampler_cso);
> -
> -   if (aaline->texture)
> -      pipe_resource_reference(&aaline->texture, NULL);
> -
> -   if (aaline->sampler_view) {
> -      pipe_sampler_view_reference(&aaline->sampler_view, NULL);
> -   }
>   
>      draw_free_temp_verts(stage);
>   
> @@ -767,9 +530,6 @@ aaline_destroy(struct draw_stage *stage)
>      pipe->bind_fs_state = aaline->driver_bind_fs_state;
>      pipe->delete_fs_state = aaline->driver_delete_fs_state;
>   
> -   pipe->bind_sampler_states = aaline->driver_bind_sampler_states;
> -   pipe->set_sampler_views = aaline->driver_set_sampler_views;
> -
>      FREE(stage);
>   }
>   
> @@ -884,57 +644,6 @@ aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
>   }
>   
>   
> -static void
> -aaline_bind_sampler_states(struct pipe_context *pipe,
> -                           enum pipe_shader_type shader,
> -                           unsigned start, unsigned num, void **sampler)
> -{
> -   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
> -
> -   assert(start == 0);
> -
> -   if (!aaline) {
> -      return;
> -   }
> -
> -   if (shader == PIPE_SHADER_FRAGMENT) {
> -      /* save current */
> -      memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
> -      aaline->num_samplers = num;
> -   }
> -
> -   /* pass-through */
> -   aaline->driver_bind_sampler_states(pipe, shader, start, num, sampler);
> -}
> -
> -
> -static void
> -aaline_set_sampler_views(struct pipe_context *pipe,
> -                         enum pipe_shader_type shader,
> -                         unsigned start, unsigned num,
> -                         struct pipe_sampler_view **views)
> -{
> -   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
> -   uint i;
> -
> -   if (!aaline) {
> -      return;
> -   }
> -
> -   if (shader == PIPE_SHADER_FRAGMENT) {
> -      /* save current */
> -      for (i = 0; i < num; i++) {
> -         pipe_sampler_view_reference(&aaline->state.sampler_views[start + i],
> -                                     views[i]);
> -      }
> -      aaline->num_sampler_views = num;
> -   }
> -
> -   /* pass-through */
> -   aaline->driver_set_sampler_views(pipe, shader, start, num, views);
> -}
> -
> -
>   void
>   draw_aaline_prepare_outputs(struct draw_context *draw,
>                               struct draw_stage *stage)
> @@ -949,7 +658,7 @@ draw_aaline_prepare_outputs(struct draw_context *draw,
>         return;
>   
>      /* allocate the extra post-transformed vertex attribute */
> -   aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw,
> +   aaline->coord_slot = draw_alloc_extra_vertex_attrib(draw,
>                                                        TGSI_SEMANTIC_GENERIC,
>                                                        aaline->fs->generic_attrib);
>   }
> @@ -978,24 +687,11 @@ draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
>      aaline->driver_bind_fs_state = pipe->bind_fs_state;
>      aaline->driver_delete_fs_state = pipe->delete_fs_state;
>   
> -   aaline->driver_bind_sampler_states = pipe->bind_sampler_states;
> -   aaline->driver_set_sampler_views = pipe->set_sampler_views;
> -
> -   /* create special texture, sampler state */
> -   if (!aaline_create_texture(aaline))
> -      goto fail;
> -
> -   if (!aaline_create_sampler(aaline))
> -      goto fail;
> -
>      /* override the driver's functions */
>      pipe->create_fs_state = aaline_create_fs_state;
>      pipe->bind_fs_state = aaline_bind_fs_state;
>      pipe->delete_fs_state = aaline_delete_fs_state;
>   
> -   pipe->bind_sampler_states = aaline_bind_sampler_states;
> -   pipe->set_sampler_views = aaline_set_sampler_views;
> -
>      /* Install once everything is known to be OK:
>       */
>      draw->pipeline.aaline = &aaline->stage;
> 



More information about the mesa-dev mailing list