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

Jose Fonseca jfonseca at vmware.com
Wed Mar 7 10:34:37 UTC 2018


On 06/03/18 20:52, Brian Paul wrote:
> Looks good.  That certainly does simplify things.  Two minor 
> suggestions below.
>
> In any case, for both, Reviewed-by: Brian Paul <brianp at vmware.com>

Looks great cleanup to me too.  Just minor issues inline. Both are

Reviewed-by: Jose Fonseca <jfonseca 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);
UINT64_C(1)
>>         }
>>      }
>>   @@ -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;

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? */

You could just check for pixel_center and write an warning.

+   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