draw: rename pipeline files to draw_pipe_*
authorKeith Whitwell <keith@tungstengraphics.com>
Fri, 18 Apr 2008 23:45:05 +0000 (00:45 +0100)
committerKeith Whitwell <keith@tungstengraphics.com>
Fri, 18 Apr 2008 23:45:05 +0000 (00:45 +0100)
32 files changed:
src/gallium/auxiliary/draw/Makefile
src/gallium/auxiliary/draw/SConscript
src/gallium/auxiliary/draw/draw_aaline.c [deleted file]
src/gallium/auxiliary/draw/draw_aapoint.c [deleted file]
src/gallium/auxiliary/draw/draw_clip.c [deleted file]
src/gallium/auxiliary/draw/draw_cull.c [deleted file]
src/gallium/auxiliary/draw/draw_flatshade.c [deleted file]
src/gallium/auxiliary/draw/draw_offset.c [deleted file]
src/gallium/auxiliary/draw/draw_pipe_aaline.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_aapoint.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_clip.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_cull.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_flatshade.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_offset.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_pstipple.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_stipple.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_twoside.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_unfilled.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_validate.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_vbuf.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_wide_line.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_wide_point.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pipe_wide_prims.c [new file with mode: 0644]
src/gallium/auxiliary/draw/draw_pstipple.c [deleted file]
src/gallium/auxiliary/draw/draw_stipple.c [deleted file]
src/gallium/auxiliary/draw/draw_twoside.c [deleted file]
src/gallium/auxiliary/draw/draw_unfilled.c [deleted file]
src/gallium/auxiliary/draw/draw_validate.c [deleted file]
src/gallium/auxiliary/draw/draw_vbuf.c [deleted file]
src/gallium/auxiliary/draw/draw_wide_line.c [deleted file]
src/gallium/auxiliary/draw/draw_wide_point.c [deleted file]
src/gallium/auxiliary/draw/draw_wide_prims.c [deleted file]

index 0b0578a17985ff7f1b5697223d282eaca08824f0..62f46c6db1e3095150c6e134a0ed92a20d4a906d 100644 (file)
@@ -4,14 +4,21 @@ include $(TOP)/configs/current
 LIBNAME = draw
 
 C_SOURCES = \
-       draw_aaline.c \
-       draw_aapoint.c \
-       draw_clip.c \
-       draw_context.c\
-       draw_cull.c \
-       draw_flatshade.c \
-       draw_offset.c \
-       draw_pstipple.c \
+       draw_context.c \
+       draw_pipe_aaline.c \
+       draw_pipe_aapoint.c \
+       draw_pipe_clip.c \
+       draw_pipe_cull.c \
+       draw_pipe_flatshade.c \
+       draw_pipe_offset.c \
+       draw_pipe_pstipple.c \
+       draw_pipe_stipple.c \
+       draw_pipe_twoside.c \
+       draw_pipe_unfilled.c \
+       draw_pipe_validate.c \
+       draw_pipe_vbuf.c \
+       draw_pipe_wide_line.c \
+       draw_pipe_wide_point.c \
        draw_pt.c \
        draw_pt_elts.c \
        draw_pt_emit.c \
@@ -21,18 +28,11 @@ C_SOURCES = \
        draw_pt_pipeline.c \
        draw_pt_post_vs.c \
        draw_pt_vcache.c \
-       draw_stipple.c \
-       draw_twoside.c \
-       draw_unfilled.c \
-       draw_validate.c \
-       draw_vbuf.c \
        draw_vertex.c \
        draw_vs.c \
        draw_vs_exec.c \
        draw_vs_llvm.c \
-       draw_vs_sse.c \
-       draw_wide_line.c \
-       draw_wide_point.c
+       draw_vs_sse.c 
 
 
 include ../../Makefile.template
index 388d7879dd65e6102240c7d4cd9d3201641edb83..5fa35d3005610204f3fccff3298c76ee935dddcd 100644 (file)
@@ -3,14 +3,22 @@ Import('*')
 draw = env.ConvenienceLibrary(
        target = 'draw',
        source = [
-               'draw_aaline.c',
-               'draw_aapoint.c',
-               'draw_clip.c',
                'draw_context.c',
-               'draw_cull.c',
-               'draw_flatshade.c',
-               'draw_offset.c',
-               'draw_pstipple.c',
+               'draw_pipe_aaline.c',
+               'draw_pipe_aapoint.c',
+               'draw_pipe_clip.c',
+               'draw_pipe_cull.c',
+               'draw_pipe_flatshade.c',
+               'draw_pipe_offset.c',
+               'draw_pipe_pstipple.c',
+               'draw_pipe_stipple.c',
+               'draw_pipe_twoside.c',
+               'draw_pipe_unfilled.c',
+               'draw_pipe_validate.c',
+               'draw_pipe_vbuf.c',
+               'draw_pipe_vertex.c',
+               'draw_pipe_wide_line.c',
+               'draw_pipe_wide_point.c',
                'draw_pt.c',
                'draw_pt_elts.c',
                'draw_pt_emit.c',
@@ -20,18 +28,10 @@ draw = env.ConvenienceLibrary(
                'draw_pt_pipeline.c',
                'draw_pt_post_vs.c',
                'draw_pt_vcache.c',
-               'draw_stipple.c',
-               'draw_twoside.c',
-               'draw_unfilled.c',
-               'draw_validate.c',
-               'draw_vbuf.c',
-               'draw_vertex.c',
                'draw_vs.c',
                'draw_vs_exec.c',
                'draw_vs_llvm.c',
                'draw_vs_sse.c',
-               'draw_wide_line.c',
-               'draw_wide_point.c',
        ])
 
 auxiliaries.insert(0, draw)
diff --git a/src/gallium/auxiliary/draw/draw_aaline.c b/src/gallium/auxiliary/draw/draw_aaline.c
deleted file mode 100644 (file)
index e8d2a45..0000000
+++ /dev/null
@@ -1,859 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * AA line stage:  AA lines are converted to texture mapped triangles.
- *
- * Authors:  Brian Paul
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "tgsi/util/tgsi_transform.h"
-#include "tgsi/util/tgsi_dump.h"
-
-#include "draw_context.h"
-#include "draw_private.h"
-
-
-/**
- * Max texture level for the alpha texture used for antialiasing
- */
-#define MAX_TEXTURE_LEVEL  5   /* 32 x 32 */
-
-
-/**
- * Subclass of pipe_shader_state to carry extra fragment shader info.
- */
-struct aaline_fragment_shader
-{
-   struct pipe_shader_state state;
-   void *driver_fs;
-   void *aaline_fs;
-   void *aapoint_fs; /* not yet */
-   void *sprite_fs; /* not yet */
-   uint sampler_unit;
-   int generic_attrib;  /**< texcoord/generic used for texture */
-};
-
-
-/**
- * Subclass of draw_stage
- */
-struct aaline_stage
-{
-   struct draw_stage stage;
-
-   float half_line_width;
-
-   /** For AA lines, this is the vertex attrib slot for the new texcoords */
-   uint tex_slot;
-
-   void *sampler_cso;
-   struct pipe_texture *texture;
-   uint num_samplers;
-   uint num_textures;
-
-
-   /*
-    * Currently bound state
-    */
-   struct aaline_fragment_shader *fs;
-   struct {
-      void *sampler[PIPE_MAX_SAMPLERS];
-      struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
-   } state;
-
-   /*
-    * Driver interface/override functions
-    */
-   void * (*driver_create_fs_state)(struct pipe_context *,
-                                    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 *, unsigned,
-                                      void **);
-   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
-                                       struct pipe_texture **);
-
-   struct pipe_context *pipe;
-};
-
-
-
-/**
- * Subclass of tgsi_transform_context, used for transforming the
- * user's fragment shader to add the special AA instructions.
- */
-struct aa_transform_context {
-   struct tgsi_transform_context base;
-   uint tempsUsed;  /**< bitmask */
-   int colorOutput; /**< which output is the primary color */
-   uint samplersUsed;  /**< bitfield of samplers used */
-   int freeSampler;  /** an available sampler for the pstipple */
-   int maxInput, maxGeneric;  /**< max input index found */
-   int colorTemp, texTemp;  /**< temp registers */
-   boolean firstInstruction;
-};
-
-
-/**
- * TGSI declaration transform callback.
- * Look for a free sampler, 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;
-
-   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
-       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
-       decl->Semantic.SemanticIndex == 0) {
-      aactx->colorOutput = decl->u.DeclarationRange.First;
-   }
-   else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
-      uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
-         aactx->samplersUsed |= 1 << i;
-      }
-   }
-   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
-         aactx->maxInput = decl->u.DeclarationRange.Last;
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
-           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
-         aactx->maxGeneric = decl->Semantic.SemanticIndex;
-      }
-   }
-   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
-      uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
-         aactx->tempsUsed |= (1 << i);
-      }
-   }
-
-   ctx->emit_declaration(ctx, decl);
-}
-
-
-/**
- * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
- */
-static int
-free_bit(uint bitfield)
-{
-   int i;
-   for (i = 0; i < 32; i++) {
-      if ((bitfield & (1 << i)) == 0)
-         return i;
-   }
-   return -1;
-}
-
-
-/**
- * TGSI instruction transform callback.
- * Replace writes to result.color w/ a temp reg.
- * Upon END instruction, insert texture sampling code for antialiasing.
- */
-static void
-aa_transform_inst(struct tgsi_transform_context *ctx,
-                  struct tgsi_full_instruction *inst)
-{
-   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
-
-   if (aactx->firstInstruction) {
-      /* emit our new declarations before the first instruction */
-
-      struct tgsi_full_declaration decl;
-      uint i;
-
-      /* find free sampler */
-      aactx->freeSampler = free_bit(aactx->samplersUsed);
-      if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
-         aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
-
-      /* find two free temp regs */
-      for (i = 0; i < 32; 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
-               break;
-         }
-      }
-      assert(aactx->colorTemp >= 0);
-      assert(aactx->texTemp >= 0);
-
-      /* declare new generic input/texcoord */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_INPUT;
-      decl.Declaration.Semantic = 1;
-      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
-      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
-      decl.Declaration.Interpolate = 1;
-      /* XXX this could be linear... */
-      decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->maxInput + 1;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* declare new sampler */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_SAMPLER;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->freeSampler;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* declare new temp regs */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->texTemp;
-      ctx->emit_declaration(ctx, &decl);
-
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->colorTemp;
-      ctx->emit_declaration(ctx, &decl);
-
-      aactx->firstInstruction = FALSE;
-   }
-
-   if (inst->Instruction.Opcode == TGSI_OPCODE_END &&
-       aactx->colorOutput != -1) {
-      struct tgsi_full_instruction newInst;
-
-      /* TEX */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
-
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* MOV rgb */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* MUL alpha */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* END */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_END;
-      newInst.Instruction.NumDstRegs = 0;
-      newInst.Instruction.NumSrcRegs = 0;
-      ctx->emit_instruction(ctx, &newInst);
-   }
-   else {
-      /* Not an END instruction.
-       * Look for writes to result.color and replace with colorTemp reg.
-       */
-      uint i;
-
-      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
-             dst->DstRegister.Index == aactx->colorOutput) {
-            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
-            dst->DstRegister.Index = aactx->colorTemp;
-         }
-      }
-
-      ctx->emit_instruction(ctx, inst);
-   }
-}
-
-
-/**
- * Generate the frag shader we'll use for drawing AA lines.
- * This will be the user's shader plus some texture/modulate instructions.
- */
-static void
-generate_aaline_fs(struct aaline_stage *aaline)
-{
-   const struct pipe_shader_state *orig_fs = &aaline->fs->state;
-   //struct draw_context *draw = aaline->stage.draw;
-   struct pipe_shader_state aaline_fs;
-   struct aa_transform_context transform;
-
-#define MAX 1000
-
-   aaline_fs = *orig_fs; /* copy to init */
-   aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
-
-   memset(&transform, 0, sizeof(transform));
-   transform.colorOutput = -1;
-   transform.maxInput = -1;
-   transform.maxGeneric = -1;
-   transform.colorTemp = -1;
-   transform.texTemp = -1;
-   transform.firstInstruction = TRUE;
-   transform.base.transform_instruction = aa_transform_inst;
-   transform.base.transform_declaration = aa_transform_decl;
-
-   tgsi_transform_shader(orig_fs->tokens,
-                         (struct tgsi_token *) aaline_fs.tokens,
-                         MAX, &transform.base);
-
-#if 0 /* DEBUG */
-   tgsi_dump(orig_fs->tokens, 0);
-   tgsi_dump(aaline_fs.tokens, 0);
-#endif
-
-   aaline->fs->sampler_unit = transform.freeSampler;
-
-   aaline->fs->aaline_fs
-      = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
-
-   aaline->fs->generic_attrib = transform.maxGeneric + 1;
-}
-
-
-/**
- * Create the texture map we'll use for antialiasing the lines.
- */
-static void
-aaline_create_texture(struct aaline_stage *aaline)
-{
-   struct pipe_context *pipe = aaline->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_texture texTemp;
-   uint level;
-
-   memset(&texTemp, 0, sizeof(texTemp));
-   texTemp.target = PIPE_TEXTURE_2D;
-   texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */
-   texTemp.last_level = MAX_TEXTURE_LEVEL;
-   texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL;
-   texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL;
-   texTemp.depth[0] = 1;
-   texTemp.cpp = 1;
-
-   aaline->texture = screen->texture_create(screen, &texTemp);
-
-   /* 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.
-    */
-   for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
-      struct pipe_surface *surface;
-      const uint size = aaline->texture->width[level];
-      ubyte *data;
-      uint i, j;
-
-      assert(aaline->texture->width[level] == aaline->texture->height[level]);
-
-      surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0);
-      data = pipe_surface_map(surface);
-
-      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 = 0;
-            }
-            else {
-               d = 255;
-            }
-            data[i * surface->pitch + j] = d;
-         }
-      }
-
-      /* unmap */
-      pipe_surface_unmap(surface);
-      pipe_surface_reference(&surface, NULL);
-      pipe->texture_update(pipe, aaline->texture, 0, (1 << level));
-   }
-}
-
-
-/**
- * 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 void
-aaline_create_sampler(struct aaline_stage *aaline)
-{
-   struct pipe_sampler_state sampler;
-   struct pipe_context *pipe = aaline->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);
-}
-
-
-/**
- * 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.
- */
-static void
-bind_aaline_fragment_shader(struct aaline_stage *aaline)
-{
-   if (!aaline->fs->aaline_fs) {
-      generate_aaline_fs(aaline);
-   }
-   aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
-}
-
-
-
-static INLINE struct aaline_stage *
-aaline_stage( struct draw_stage *stage )
-{
-   return (struct aaline_stage *) stage;
-}
-
-
-static void
-passthrough_point(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->point(stage->next, header);
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-/**
- * Draw a wide line by drawing a quad, using geometry which will
- * fullfill GL's antialiased line requirements.
- */
-static void
-aaline_line(struct draw_stage *stage, struct prim_header *header)
-{
-   const struct aaline_stage *aaline = aaline_stage(stage);
-   const float half_width = aaline->half_line_width;
-   struct prim_header tri;
-   struct vertex_header *v[8];
-   uint texPos = aaline->tex_slot;
-   float *pos, *tex;
-   float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0];
-   float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1];
-   double a = atan2(dy, dx);
-   float c_a = (float) cos(a), s_a = (float) sin(a);
-   uint i;
-
-   /* XXX the ends of lines aren't quite perfect yet, but probably passable */
-   dx = 0.5F * half_width;
-   dy = half_width;
-
-   /* allocate/dup new verts */
-   for (i = 0; i < 8; i++) {
-      v[i] = dup_vert(stage, header->v[i/4], i);
-   }
-
-   /*
-    * Quad strip for line from v0 to v1 (*=endpoints):
-    *
-    *  1   3                     5   7
-    *  +---+---------------------+---+
-    *  |                             |
-    *  | *v0                     v1* |
-    *  |                             |
-    *  +---+---------------------+---+
-    *  0   2                     4   6
-    */
-
-   /* new verts */
-   pos = v[0]->data[0];
-   pos[0] += (-dx * c_a -  dy * s_a);
-   pos[1] += (-dx * s_a +  dy * c_a);
-
-   pos = v[1]->data[0];
-   pos[0] += (-dx * c_a - -dy * s_a);
-   pos[1] += (-dx * s_a + -dy * c_a);
-
-   pos = v[2]->data[0];
-   pos[0] += ( dx * c_a -  dy * s_a);
-   pos[1] += ( dx * s_a +  dy * c_a);
-
-   pos = v[3]->data[0];
-   pos[0] += ( dx * c_a - -dy * s_a);
-   pos[1] += ( dx * s_a + -dy * c_a);
-
-   pos = v[4]->data[0];
-   pos[0] += (-dx * c_a -  dy * s_a);
-   pos[1] += (-dx * s_a +  dy * c_a);
-
-   pos = v[5]->data[0];
-   pos[0] += (-dx * c_a - -dy * s_a);
-   pos[1] += (-dx * s_a + -dy * c_a);
-
-   pos = v[6]->data[0];
-   pos[0] += ( dx * c_a -  dy * s_a);
-   pos[1] += ( dx * s_a +  dy * c_a);
-
-   pos = v[7]->data[0];
-   pos[0] += ( dx * c_a - -dy * s_a);
-   pos[1] += ( dx * s_a + -dy * 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[3]->data[texPos];
-   ASSIGN_4V(tex, .5, 1, 0, 1);
-
-   tex = v[4]->data[texPos];
-   ASSIGN_4V(tex, .5, 0, 0, 1);
-
-   tex = v[5]->data[texPos];
-   ASSIGN_4V(tex, .5, 1, 0, 1);
-
-   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 );
-}
-
-
-static void
-aaline_first_line(struct draw_stage *stage, struct prim_header *header)
-{
-   auto struct aaline_stage *aaline = aaline_stage(stage);
-   struct draw_context *draw = stage->draw;
-   struct pipe_context *pipe = aaline->pipe;
-   uint num_samplers;
-
-   assert(draw->rasterizer->line_smooth);
-
-   if (draw->rasterizer->line_width <= 3.0)
-      aaline->half_line_width = 1.5f;
-   else
-      aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
-
-   /*
-    * Bind (generate) our fragprog, sampler and texture
-    */
-   bind_aaline_fragment_shader(aaline);
-
-   /* update vertex attrib info */
-   aaline->tex_slot = draw->num_vs_outputs;
-   assert(aaline->tex_slot > 0); /* output[0] is vertex pos */
-
-   /* advertise the extra post-transformed vertex attribute */
-   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
-   draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
-   draw->extra_vp_outputs.slot = aaline->tex_slot;
-
-   /* how many samplers? */
-   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
-   num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
-   num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
-
-   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
-   pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
-                          aaline->texture);
-
-   aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
-   aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
-
-   /* now really draw first line */
-   stage->line = aaline_line;
-   stage->line(stage, header);
-}
-
-
-static void
-aaline_flush(struct draw_stage *stage, unsigned flags)
-{
-   struct draw_context *draw = stage->draw;
-   struct aaline_stage *aaline = aaline_stage(stage);
-   struct pipe_context *pipe = aaline->pipe;
-
-   stage->line = aaline_first_line;
-   stage->next->flush( stage->next, flags );
-
-   /* restore original frag shader */
-   aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
-
-   /* XXX restore original texture, sampler state */
-   aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
-                                      aaline->state.sampler);
-   aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
-                                       aaline->state.texture);
-
-   draw->extra_vp_outputs.slot = 0;
-}
-
-
-static void
-aaline_reset_stipple_counter(struct draw_stage *stage)
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void
-aaline_destroy(struct draw_stage *stage)
-{
-   struct aaline_stage *aaline = aaline_stage(stage);
-
-   aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
-
-   pipe_texture_release(&aaline->texture);
-
-   draw_free_temp_verts( stage );
-
-   FREE( stage );
-}
-
-
-static struct aaline_stage *
-draw_aaline_stage(struct draw_context *draw)
-{
-   struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
-
-   draw_alloc_temp_verts( &aaline->stage, 8 );
-
-   aaline->stage.draw = draw;
-   aaline->stage.next = NULL;
-   aaline->stage.point = passthrough_point;
-   aaline->stage.line = aaline_first_line;
-   aaline->stage.tri = passthrough_tri;
-   aaline->stage.flush = aaline_flush;
-   aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter;
-   aaline->stage.destroy = aaline_destroy;
-
-   return aaline;
-}
-
-
-static struct aaline_stage *
-aaline_stage_from_pipe(struct pipe_context *pipe)
-{
-   struct draw_context *draw = (struct draw_context *) pipe->draw;
-   return aaline_stage(draw->pipeline.aaline);
-}
-
-
-/**
- * This function overrides the driver's create_fs_state() function and
- * will typically be called by the state tracker.
- */
-static void *
-aaline_create_fs_state(struct pipe_context *pipe,
-                       const struct pipe_shader_state *fs)
-{
-   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
-
-   if (aafs) {
-      aafs->state = *fs;
-
-      /* pass-through */
-      aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
-   }
-
-   return aafs;
-}
-
-
-static void
-aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
-   /* save current */
-   aaline->fs = aafs;
-   /* pass-through */
-   aaline->driver_bind_fs_state(aaline->pipe,
-                                (aafs ? aafs->driver_fs : NULL));
-}
-
-
-static void
-aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
-   /* pass-through */
-   aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
-   FREE(aafs);
-}
-
-
-static void
-aaline_bind_sampler_states(struct pipe_context *pipe,
-                           unsigned num, void **sampler)
-{
-   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   /* save current */
-   memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
-   aaline->num_samplers = num;
-   /* pass-through */
-   aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
-}
-
-
-static void
-aaline_set_sampler_textures(struct pipe_context *pipe,
-                            unsigned num, struct pipe_texture **texture)
-{
-   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
-   uint i;
-
-   /* save current */
-   for (i = 0; i < num; i++) {
-      pipe_texture_reference(&aaline->state.texture[i], texture[i]);
-   }
-   aaline->num_textures = num;
-
-   /* pass-through */
-   aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
-}
-
-
-/**
- * Called by drivers that want to install this AA line prim stage
- * into the draw module's pipeline.  This will not be used if the
- * hardware has native support for AA lines.
- */
-void
-draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
-{
-   struct aaline_stage *aaline;
-
-   pipe->draw = (void *) draw;
-
-   /*
-    * Create / install AA line drawing / prim stage
-    */
-   aaline = draw_aaline_stage( draw );
-   assert(aaline);
-   draw->pipeline.aaline = &aaline->stage;
-
-   aaline->pipe = pipe;
-
-   /* create special texture, sampler state */
-   aaline_create_texture(aaline);
-   aaline_create_sampler(aaline);
-
-   /* save original driver functions */
-   aaline->driver_create_fs_state = pipe->create_fs_state;
-   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_textures = pipe->set_sampler_textures;
-
-   /* 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_textures = aaline_set_sampler_textures;
-}
diff --git a/src/gallium/auxiliary/draw/draw_aapoint.c b/src/gallium/auxiliary/draw/draw_aapoint.c
deleted file mode 100644 (file)
index e84d380..0000000
+++ /dev/null
@@ -1,846 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * AA point stage:  AA points are converted to quads and rendered with a
- * special fragment shader.  Another approach would be to use a texture
- * map image of a point, but experiments indicate the quality isn't nearly
- * as good as this approach.
- *
- * Note: this looks a lot like draw_aaline.c but there's actually little
- * if any code that can be shared.
- *
- * Authors:  Brian Paul
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "tgsi/util/tgsi_transform.h"
-#include "tgsi/util/tgsi_dump.h"
-
-#include "draw_context.h"
-#include "draw_vs.h"
-
-
-/*
- * Enabling NORMALIZE might give _slightly_ better results.
- * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or
- * d=x*x+y*y.  Since we're working with a unit circle, the later seems
- * close enough and saves some costly instructions.
- */
-#define NORMALIZE 0
-
-
-/**
- * Subclass of pipe_shader_state to carry extra fragment shader info.
- */
-struct aapoint_fragment_shader
-{
-   struct pipe_shader_state state;
-   void *driver_fs;   /**< the regular shader */
-   void *aapoint_fs;  /**< the aa point-augmented shader */
-   int generic_attrib; /**< The generic input attrib/texcoord we'll use */
-};
-
-
-/**
- * Subclass of draw_stage
- */
-struct aapoint_stage
-{
-   struct draw_stage stage;
-
-   int psize_slot;
-   float radius;
-
-   /** this is the vertex attrib slot for the new texcoords */
-   uint tex_slot;
-
-   /*
-    * Currently bound state
-    */
-   struct aapoint_fragment_shader *fs;
-
-   /*
-    * Driver interface/override functions
-    */
-   void * (*driver_create_fs_state)(struct pipe_context *,
-                                    const struct pipe_shader_state *);
-   void (*driver_bind_fs_state)(struct pipe_context *, void *);
-   void (*driver_delete_fs_state)(struct pipe_context *, void *);
-
-   struct pipe_context *pipe;
-};
-
-
-
-/**
- * Subclass of tgsi_transform_context, used for transforming the
- * user's fragment shader to add the special AA instructions.
- */
-struct aa_transform_context {
-   struct tgsi_transform_context base;
-   uint tempsUsed;  /**< bitmask */
-   int colorOutput; /**< which output is the primary color */
-   int maxInput, maxGeneric;  /**< max input index found */
-   int tmp0, colorTemp;  /**< temp registers */
-   boolean firstInstruction;
-};
-
-
-/**
- * TGSI declaration transform callback.
- * Look for two free temp regs and available input reg for new texcoords.
- */
-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;
-
-   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
-       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
-       decl->Semantic.SemanticIndex == 0) {
-      aactx->colorOutput = decl->u.DeclarationRange.First;
-   }
-   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
-         aactx->maxInput = decl->u.DeclarationRange.Last;
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
-           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
-         aactx->maxGeneric = decl->Semantic.SemanticIndex;
-      }
-   }
-   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
-      uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
-         aactx->tempsUsed |= (1 << i);
-      }
-   }
-
-   ctx->emit_declaration(ctx, decl);
-}
-
-
-/**
- * TGSI instruction transform callback.
- * Replace writes to result.color w/ a temp reg.
- * Upon END instruction, insert texture sampling code for antialiasing.
- */
-static void
-aa_transform_inst(struct tgsi_transform_context *ctx,
-                  struct tgsi_full_instruction *inst)
-{
-   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
-   struct tgsi_full_instruction newInst;
-
-   if (aactx->firstInstruction) {
-      /* emit our new declarations before the first instruction */
-
-      struct tgsi_full_declaration decl;
-      const int texInput = aactx->maxInput + 1;
-      int tmp0;
-      uint i;
-
-      /* find two free temp regs */
-      for (i = 0; i < 32; i++) {
-         if ((aactx->tempsUsed & (1 << i)) == 0) {
-            /* found a free temp */
-            if (aactx->tmp0 < 0)
-               aactx->tmp0 = i;
-            else if (aactx->colorTemp < 0)
-               aactx->colorTemp = i;
-            else
-               break;
-         }
-      }
-
-      assert(aactx->colorTemp != aactx->tmp0);
-
-      tmp0 = aactx->tmp0;
-
-      /* declare new generic input/texcoord */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_INPUT;
-      decl.Declaration.Semantic = 1;
-      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
-      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
-      decl.Declaration.Interpolate = 1;
-      /* XXX this could be linear... */
-      decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = texInput;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* declare new temp regs */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = tmp0;
-      ctx->emit_declaration(ctx, &decl);
-
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = aactx->colorTemp;
-      ctx->emit_declaration(ctx, &decl);
-
-      aactx->firstInstruction = FALSE;
-
-
-      /*
-       * Emit code to compute fragment coverage, kill if outside point radius
-       *
-       * Temp reg0 usage:
-       *  t0.x = distance of fragment from center point
-       *  t0.y = boolean, is t0.x > 1.0, also misc temp usage
-       *  t0.z = temporary for computing 1/(1-k) value
-       *  t0.w = final coverage value
-       */
-
-      /* MUL t0.xy, tex, tex;  # compute x^2, y^2 */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-      ctx->emit_instruction(ctx, &newInst);
-
-#if NORMALIZE  /* OPTIONAL normalization of length */
-      /* RSQ t0.x, t0.x; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* RCP t0.x, t0.x; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      ctx->emit_instruction(ctx, &newInst);
-#endif
-
-      /* SGT t0.y, t0.xxxx, t0.wwww;  # bool b = d > 1 (NOTE t0.w == 1) */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* KILP -t0.yyyy;   # if b, KILL */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
-      newInst.Instruction.NumDstRegs = 0;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
-      ctx->emit_instruction(ctx, &newInst);
-
-
-      /* compute coverage factor = (1-d)/(1-k) */
-
-      /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* RCP t0.z, t0.z;  # t0.z = 1 / m */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* SUB t0.y, 1, t0.x;  # d = 1 - d */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* CMP t0.w, -t0.y, tex.w, t0.w;
-       *  # if -t0.y < 0 then
-       *       t0.w = 1
-       *    else
-       *       t0.w = t0.w
-       */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
-      newInst.Instruction.NumSrcRegs = 3;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
-      newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
-      ctx->emit_instruction(ctx, &newInst);
-
-   }
-
-   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
-      /* add alpha modulation code at tail of program */
-
-      /* MOV result.color.xyz, colorTemp; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* MUL result.color.w, colorTemp, tmp0.w; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
-      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
-      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0;
-      ctx->emit_instruction(ctx, &newInst);
-   }
-   else {
-      /* Not an END instruction.
-       * Look for writes to result.color and replace with colorTemp reg.
-       */
-      uint i;
-
-      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
-         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
-         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
-             dst->DstRegister.Index == aactx->colorOutput) {
-            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
-            dst->DstRegister.Index = aactx->colorTemp;
-         }
-      }
-   }
-
-   ctx->emit_instruction(ctx, inst);
-}
-
-
-/**
- * Generate the frag shader we'll use for drawing AA lines.
- * This will be the user's shader plus some texture/modulate instructions.
- */
-static void
-generate_aapoint_fs(struct aapoint_stage *aapoint)
-{
-   const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
-   struct pipe_shader_state aapoint_fs;
-   struct aa_transform_context transform;
-
-#define MAX 1000
-
-   aapoint_fs = *orig_fs; /* copy to init */
-   aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
-
-   memset(&transform, 0, sizeof(transform));
-   transform.colorOutput = -1;
-   transform.maxInput = -1;
-   transform.maxGeneric = -1;
-   transform.colorTemp = -1;
-   transform.tmp0 = -1;
-   transform.firstInstruction = TRUE;
-   transform.base.transform_instruction = aa_transform_inst;
-   transform.base.transform_declaration = aa_transform_decl;
-
-   tgsi_transform_shader(orig_fs->tokens,
-                         (struct tgsi_token *) aapoint_fs.tokens,
-                         MAX, &transform.base);
-
-#if 0 /* DEBUG */
-   printf("draw_aapoint, orig shader:\n");
-   tgsi_dump(orig_fs->tokens, 0);
-   printf("draw_aapoint, new shader:\n");
-   tgsi_dump(aapoint_fs.tokens, 0);
-#endif
-
-   aapoint->fs->aapoint_fs
-      = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
-
-   aapoint->fs->generic_attrib = transform.maxGeneric + 1;
-}
-
-
-/**
- * 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.
- */
-static void
-bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
-{
-   if (!aapoint->fs->aapoint_fs) {
-      generate_aapoint_fs(aapoint);
-   }
-   aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
-}
-
-
-
-static INLINE struct aapoint_stage *
-aapoint_stage( struct draw_stage *stage )
-{
-   return (struct aapoint_stage *) stage;
-}
-
-
-static void
-passthrough_line(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->line(stage->next, header);
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-/**
- * Draw an AA point by drawing a quad.
- */
-static void
-aapoint_point(struct draw_stage *stage, struct prim_header *header)
-{
-   const struct aapoint_stage *aapoint = aapoint_stage(stage);
-   struct prim_header tri;
-   struct vertex_header *v[4];
-   uint texPos = aapoint->tex_slot;
-   float radius, *pos, *tex;
-   uint i;
-   float k;
-
-   if (aapoint->psize_slot >= 0) {
-      radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0];
-   }
-   else {
-      radius = aapoint->radius;
-   }
-
-   /*
-    * Note: the texcoords (generic attrib, really) we use are special:
-    * The S and T components simply vary from -1 to +1.
-    * The R component is k, below.
-    * The Q component is 1.0 and will used as a handy constant in the
-    * fragment shader.
-    */
-
-   /*
-    * k is the threshold distance from the point's center at which
-    * we begin alpha attenuation (the coverage value).
-    * Operating within a unit circle, we'll compute the fragment's
-    * distance 'd' from the center point using the texcoords.
-    * IF d > 1.0 THEN
-    *    KILL fragment
-    * ELSE IF d > k THEN
-    *    compute coverage in [0,1] proportional to d in [k, 1].
-    * ELSE
-    *    coverage = 1.0;  // full coverage
-    * ENDIF
-    *
-    * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to
-    * avoid using IF/ELSE/ENDIF TGSI opcodes.
-    */
-
-#if !NORMALIZE
-   k = 1.0f / radius;
-   k = 1.0f - 2.0f * k + k * k;
-#else
-   k = 1.0f - 1.0f / radius;
-#endif
-
-   /* allocate/dup new verts */
-   for (i = 0; i < 4; i++) {
-      v[i] = dup_vert(stage, header->v[0], i);
-   }
-
-   /* new verts */
-   pos = v[0]->data[0];
-   pos[0] -= radius;
-   pos[1] -= radius;
-
-   pos = v[1]->data[0];
-   pos[0] += radius;
-   pos[1] -= radius;
-
-   pos = v[2]->data[0];
-   pos[0] += radius;
-   pos[1] += radius;
-
-   pos = v[3]->data[0];
-   pos[0] -= radius;
-   pos[1] += radius;
-
-   /* new texcoords */
-   tex = v[0]->data[texPos];
-   ASSIGN_4V(tex, -1, -1, k, 1);
-
-   tex = v[1]->data[texPos];
-   ASSIGN_4V(tex,  1, -1, k, 1);
-
-   tex = v[2]->data[texPos];
-   ASSIGN_4V(tex,  1,  1, k, 1);
-
-   tex = v[3]->data[texPos];
-   ASSIGN_4V(tex, -1,  1, k, 1);
-
-   /* emit 2 tris for the quad strip */
-   tri.v[0] = v[0];
-   tri.v[1] = v[1];
-   tri.v[2] = v[2];
-   stage->next->tri( stage->next, &tri );
-
-   tri.v[0] = v[0];
-   tri.v[1] = v[2];
-   tri.v[2] = v[3];
-   stage->next->tri( stage->next, &tri );
-}
-
-
-static void
-aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
-{
-   auto struct aapoint_stage *aapoint = aapoint_stage(stage);
-   struct draw_context *draw = stage->draw;
-
-   assert(draw->rasterizer->point_smooth);
-
-   if (draw->rasterizer->point_size <= 2.0)
-      aapoint->radius = 1.0;
-   else
-      aapoint->radius = 0.5f * draw->rasterizer->point_size;
-
-   /*
-    * Bind (generate) our fragprog.
-    */
-   bind_aapoint_fragment_shader(aapoint);
-
-   /* update vertex attrib info */
-   aapoint->tex_slot = draw->num_vs_outputs;
-   assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
-
-   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
-   draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
-   draw->extra_vp_outputs.slot = aapoint->tex_slot;
-
-   /* find psize slot in post-transform vertex */
-   aapoint->psize_slot = -1;
-   if (draw->rasterizer->point_size_per_vertex) {
-      /* find PSIZ vertex output */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
-      uint i;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
-            aapoint->psize_slot = i;
-            break;
-         }
-      }
-   }
-
-   /* now really draw first line */
-   stage->point = aapoint_point;
-   stage->point(stage, header);
-}
-
-
-static void
-aapoint_flush(struct draw_stage *stage, unsigned flags)
-{
-   struct draw_context *draw = stage->draw;
-   struct aapoint_stage *aapoint = aapoint_stage(stage);
-   struct pipe_context *pipe = aapoint->pipe;
-
-   stage->point = aapoint_first_point;
-   stage->next->flush( stage->next, flags );
-
-   /* restore original frag shader */
-   aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
-
-   draw->extra_vp_outputs.slot = 0;
-}
-
-
-static void
-aapoint_reset_stipple_counter(struct draw_stage *stage)
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void
-aapoint_destroy(struct draw_stage *stage)
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-static struct aapoint_stage *
-draw_aapoint_stage(struct draw_context *draw)
-{
-   struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
-
-   draw_alloc_temp_verts( &aapoint->stage, 4 );
-
-   aapoint->stage.draw = draw;
-   aapoint->stage.next = NULL;
-   aapoint->stage.point = aapoint_first_point;
-   aapoint->stage.line = passthrough_line;
-   aapoint->stage.tri = passthrough_tri;
-   aapoint->stage.flush = aapoint_flush;
-   aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
-   aapoint->stage.destroy = aapoint_destroy;
-
-   return aapoint;
-}
-
-
-static struct aapoint_stage *
-aapoint_stage_from_pipe(struct pipe_context *pipe)
-{
-   struct draw_context *draw = (struct draw_context *) pipe->draw;
-   return aapoint_stage(draw->pipeline.aapoint);
-}
-
-
-/**
- * This function overrides the driver's create_fs_state() function and
- * will typically be called by the state tracker.
- */
-static void *
-aapoint_create_fs_state(struct pipe_context *pipe,
-                       const struct pipe_shader_state *fs)
-{
-   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
-   struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
-
-   if (aafs) {
-      aafs->state = *fs;
-
-      /* pass-through */
-      aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
-   }
-
-   return aafs;
-}
-
-
-static void
-aapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
-   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
-   /* save current */
-   aapoint->fs = aafs;
-   /* pass-through */
-   aapoint->driver_bind_fs_state(aapoint->pipe,
-                                 (aafs ? aafs->driver_fs : NULL));
-}
-
-
-static void
-aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
-   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
-   /* pass-through */
-   aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
-   FREE(aafs);
-}
-
-
-/**
- * Called by drivers that want to install this AA point prim stage
- * into the draw module's pipeline.  This will not be used if the
- * hardware has native support for AA points.
- */
-void
-draw_install_aapoint_stage(struct draw_context *draw,
-                           struct pipe_context *pipe)
-{
-   struct aapoint_stage *aapoint;
-
-   pipe->draw = (void *) draw;
-
-   /*
-    * Create / install AA point drawing / prim stage
-    */
-   aapoint = draw_aapoint_stage( draw );
-   assert(aapoint);
-   draw->pipeline.aapoint = &aapoint->stage;
-
-   aapoint->pipe = pipe;
-
-   /* save original driver functions */
-   aapoint->driver_create_fs_state = pipe->create_fs_state;
-   aapoint->driver_bind_fs_state = pipe->bind_fs_state;
-   aapoint->driver_delete_fs_state = pipe->delete_fs_state;
-
-   /* override the driver's functions */
-   pipe->create_fs_state = aapoint_create_fs_state;
-   pipe->bind_fs_state = aapoint_bind_fs_state;
-   pipe->delete_fs_state = aapoint_delete_fs_state;
-}
diff --git a/src/gallium/auxiliary/draw/draw_clip.c b/src/gallium/auxiliary/draw/draw_clip.c
deleted file mode 100644 (file)
index 0ac3a24..0000000
+++ /dev/null
@@ -1,503 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * \brief  Clipping stage
- *
- * \author  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "draw_context.h"
-#include "draw_vs.h"
-
-
-#ifndef IS_NEGATIVE
-#define IS_NEGATIVE(X) ((X) < 0.0)
-#endif
-
-#ifndef DIFFERENT_SIGNS
-#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
-#endif
-
-#ifndef MAX_CLIPPED_VERTICES
-#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
-#endif
-
-
-
-struct clipper {
-   struct draw_stage stage;      /**< base class */
-
-   /* Basically duplicate some of the flatshading logic here:
-    */
-   boolean flat;
-   uint num_color_attribs;
-   uint color_attribs[4];  /* front/back primary/secondary colors */
-
-   float (*plane)[4];
-};
-
-
-/* This is a bit confusing:
- */
-static INLINE struct clipper *clipper_stage( struct draw_stage *stage )
-{
-   return (struct clipper *)stage;
-}
-
-
-#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
-
-
-/* All attributes are float[4], so this is easy:
- */
-static void interp_attr( float *fdst,
-                        float t,
-                        const float *fin,
-                        const float *fout )
-{  
-   fdst[0] = LINTERP( t, fout[0], fin[0] );
-   fdst[1] = LINTERP( t, fout[1], fin[1] );
-   fdst[2] = LINTERP( t, fout[2], fin[2] );
-   fdst[3] = LINTERP( t, fout[3], fin[3] );
-}
-
-static void copy_colors( struct draw_stage *stage,
-                        struct vertex_header *dst,
-                        const struct vertex_header *src )
-{
-   const struct clipper *clipper = clipper_stage(stage);
-   uint i;
-   for (i = 0; i < clipper->num_color_attribs; i++) {
-      const uint attr = clipper->color_attribs[i];
-      COPY_4FV(dst->data[attr], src->data[attr]);
-   }
-}
-
-
-
-/* Interpolate between two vertices to produce a third.  
- */
-static void interp( const struct clipper *clip,
-                   struct vertex_header *dst,
-                   float t,
-                   const struct vertex_header *out, 
-                   const struct vertex_header *in )
-{
-   const unsigned nr_attrs = clip->stage.draw->num_vs_outputs;
-   unsigned j;
-
-   /* Vertex header.
-    */
-   {
-      dst->clipmask = 0;
-      dst->edgeflag = 0;
-      dst->pad = 0;
-      dst->vertex_id = UNDEFINED_VERTEX_ID;
-   }
-
-   /* Clip coordinates:  interpolate normally
-    */
-   {
-      interp_attr(dst->clip, t, in->clip, out->clip);
-   }
-
-   /* Do the projective divide and insert window coordinates:
-    */
-   {
-      const float *pos = dst->clip;
-      const float *scale = clip->stage.draw->viewport.scale;
-      const float *trans = clip->stage.draw->viewport.translate;
-      const float oow = 1.0f / pos[3];
-
-      dst->data[0][0] = pos[0] * oow * scale[0] + trans[0];
-      dst->data[0][1] = pos[1] * oow * scale[1] + trans[1];
-      dst->data[0][2] = pos[2] * oow * scale[2] + trans[2];
-      dst->data[0][3] = oow;
-   }
-
-   /* Other attributes
-    * Note: start at 1 to skip winpos (data[0]) since we just computed
-    * it above.
-    */
-   for (j = 1; j < nr_attrs; j++) {
-      interp_attr(dst->data[j], t, in->data[j], out->data[j]);
-   }
-}
-
-
-static void emit_poly( struct draw_stage *stage,
-                      struct vertex_header **inlist,
-                      unsigned n,
-                      const struct prim_header *origPrim)
-{
-   struct prim_header header;
-   unsigned i;
-
-   /* later stages may need the determinant, but only the sign matters */
-   header.det = origPrim->det;
-
-   for (i = 2; i < n; i++) {
-      header.v[0] = inlist[i-1];
-      header.v[1] = inlist[i];
-      header.v[2] = inlist[0]; /* keep in v[2] for flatshading */
-       
-      {
-        unsigned tmp1 = header.v[1]->edgeflag;
-        unsigned tmp2 = header.v[2]->edgeflag;
-
-        if (i != n-1) header.v[1]->edgeflag = 0;
-        if (i != 2)   header.v[2]->edgeflag = 0;
-
-         header.edgeflags = ((header.v[0]->edgeflag << 0) | 
-                             (header.v[1]->edgeflag << 1) | 
-                             (header.v[2]->edgeflag << 2));
-
-         if (0) {
-            const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
-            uint j, k;
-            debug_printf("Clipped tri:\n");
-            for (j = 0; j < 3; j++) {
-               for (k = 0; k < vs->info.num_outputs; k++) {
-                  debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
-                         header.v[j]->data[k][0],
-                         header.v[j]->data[k][1],
-                         header.v[j]->data[k][2],
-                         header.v[j]->data[k][3]);
-               }
-            }
-         }
-
-        stage->next->tri( stage->next, &header );
-
-        header.v[1]->edgeflag = tmp1;
-        header.v[2]->edgeflag = tmp2;
-      }
-   }
-}
-
-
-
-
-/* Clip a triangle against the viewport and user clip planes.
- */
-static void
-do_clip_tri( struct draw_stage *stage, 
-            struct prim_header *header,
-            unsigned clipmask )
-{
-   struct clipper *clipper = clipper_stage( stage );
-   struct vertex_header *a[MAX_CLIPPED_VERTICES];
-   struct vertex_header *b[MAX_CLIPPED_VERTICES];
-   struct vertex_header **inlist = a;
-   struct vertex_header **outlist = b;
-   unsigned tmpnr = 0;
-   unsigned n = 3;
-   unsigned i;
-
-   inlist[0] = header->v[0];
-   inlist[1] = header->v[1];
-   inlist[2] = header->v[2];
-
-   while (clipmask && n >= 3) {
-      const unsigned plane_idx = ffs(clipmask)-1;
-      const float *plane = clipper->plane[plane_idx];
-      struct vertex_header *vert_prev = inlist[0];
-      float dp_prev = dot4( vert_prev->clip, plane );
-      unsigned outcount = 0;
-
-      clipmask &= ~(1<<plane_idx);
-
-      inlist[n] = inlist[0]; /* prevent rotation of vertices */
-
-      for (i = 1; i <= n; i++) {
-        struct vertex_header *vert = inlist[i];
-
-        float dp = dot4( vert->clip, plane );
-
-        if (!IS_NEGATIVE(dp_prev)) {
-           outlist[outcount++] = vert_prev;
-        }
-
-        if (DIFFERENT_SIGNS(dp, dp_prev)) {
-           struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
-           outlist[outcount++] = new_vert;
-
-           if (IS_NEGATIVE(dp)) {
-              /* Going out of bounds.  Avoid division by zero as we
-               * know dp != dp_prev from DIFFERENT_SIGNS, above.
-               */
-              float t = dp / (dp - dp_prev);
-              interp( clipper, new_vert, t, vert, vert_prev );
-              
-              /* Force edgeflag true in this case:
-               */
-              new_vert->edgeflag = 1;
-           } else {
-              /* Coming back in.
-               */
-              float t = dp_prev / (dp_prev - dp);
-              interp( clipper, new_vert, t, vert_prev, vert );
-
-              /* Copy starting vert's edgeflag:
-               */
-              new_vert->edgeflag = vert_prev->edgeflag;
-           }
-        }
-
-        vert_prev = vert;
-        dp_prev = dp;
-      }
-
-      {
-        struct vertex_header **tmp = inlist;
-        inlist = outlist;
-        outlist = tmp;
-        n = outcount;
-      }
-   }
-
-   /* If flat-shading, copy color to new provoking vertex.
-    */
-   if (clipper->flat && inlist[0] != header->v[2]) {
-      if (1) {
-        inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
-      }
-
-      copy_colors(stage, inlist[0], header->v[2]);
-   }
-
-
-
-   /* Emit the polygon as triangles to the setup stage:
-    */
-   if (n >= 3)
-      emit_poly( stage, inlist, n, header );
-}
-
-
-/* Clip a line against the viewport and user clip planes.
- */
-static void
-do_clip_line( struct draw_stage *stage,
-             struct prim_header *header,
-             unsigned clipmask )
-{
-   const struct clipper *clipper = clipper_stage( stage );
-   struct vertex_header *v0 = header->v[0];
-   struct vertex_header *v1 = header->v[1];
-   const float *pos0 = v0->clip;
-   const float *pos1 = v1->clip;
-   float t0 = 0.0F;
-   float t1 = 0.0F;
-   struct prim_header newprim;
-
-   while (clipmask) {
-      const unsigned plane_idx = ffs(clipmask)-1;
-      const float *plane = clipper->plane[plane_idx];
-      const float dp0 = dot4( pos0, plane );
-      const float dp1 = dot4( pos1, plane );
-
-      if (dp1 < 0.0F) {
-        float t = dp1 / (dp1 - dp0);
-         t1 = MAX2(t1, t);
-      } 
-
-      if (dp0 < 0.0F) {
-        float t = dp0 / (dp0 - dp1);
-         t0 = MAX2(t0, t);
-      }
-
-      if (t0 + t1 >= 1.0F)
-        return; /* discard */
-
-      clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
-   }
-
-   if (v0->clipmask) {
-      interp( clipper, stage->tmp[0], t0, v0, v1 );
-
-      if (clipper->flat)
-        copy_colors(stage, stage->tmp[0], v0);
-
-      newprim.v[0] = stage->tmp[0];
-   }
-   else {
-      newprim.v[0] = v0;
-   }
-
-   if (v1->clipmask) {
-      interp( clipper, stage->tmp[1], t1, v1, v0 );
-      newprim.v[1] = stage->tmp[1];
-   }
-   else {
-      newprim.v[1] = v1;
-   }
-
-   stage->next->line( stage->next, &newprim );
-}
-
-
-static void
-clip_point( struct draw_stage *stage, 
-           struct prim_header *header )
-{
-   if (header->v[0]->clipmask == 0) 
-      stage->next->point( stage->next, header );
-}
-
-
-static void
-clip_line( struct draw_stage *stage,
-          struct prim_header *header )
-{
-   unsigned clipmask = (header->v[0]->clipmask | 
-                        header->v[1]->clipmask);
-   
-   if (clipmask == 0) {
-      /* no clipping needed */
-      stage->next->line( stage->next, header );
-   }
-   else if ((header->v[0]->clipmask &
-             header->v[1]->clipmask) == 0) {
-      do_clip_line(stage, header, clipmask);
-   }
-   /* else, totally clipped */
-}
-
-
-static void
-clip_tri( struct draw_stage *stage,
-         struct prim_header *header )
-{
-   unsigned clipmask = (header->v[0]->clipmask | 
-                        header->v[1]->clipmask | 
-                        header->v[2]->clipmask);
-   
-   if (clipmask == 0) {
-      /* no clipping needed */
-      stage->next->tri( stage->next, header );
-   }
-   else if ((header->v[0]->clipmask & 
-             header->v[1]->clipmask & 
-             header->v[2]->clipmask) == 0) {
-      do_clip_tri(stage, header, clipmask);
-   }
-}
-
-/* Update state.  Could further delay this until we hit the first
- * primitive that really requires clipping.
- */
-static void 
-clip_init_state( struct draw_stage *stage )
-{
-   struct clipper *clipper = clipper_stage( stage );
-
-   clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE;
-
-   if (clipper->flat) {
-      const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
-      uint i;
-
-      clipper->num_color_attribs = 0;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-        if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
-            vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-           clipper->color_attribs[clipper->num_color_attribs++] = i;
-        }
-      }
-   }
-   
-   stage->tri = clip_tri;
-   stage->line = clip_line;
-}
-
-
-
-static void clip_first_tri( struct draw_stage *stage,
-                           struct prim_header *header )
-{
-   clip_init_state( stage );
-   stage->tri( stage, header );
-}
-
-static void clip_first_line( struct draw_stage *stage,
-                            struct prim_header *header )
-{
-   clip_init_state( stage );
-   stage->line( stage, header );
-}
-
-
-static void clip_flush( struct draw_stage *stage, 
-                            unsigned flags )
-{
-   stage->tri = clip_first_tri;
-   stage->line = clip_first_line;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void clip_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void clip_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Allocate a new clipper stage.
- * \return pointer to new stage object
- */
-struct draw_stage *draw_clip_stage( struct draw_context *draw )
-{
-   struct clipper *clipper = CALLOC_STRUCT(clipper);
-
-   draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 );
-
-   clipper->stage.draw = draw;
-   clipper->stage.point = clip_point;
-   clipper->stage.line = clip_first_line;
-   clipper->stage.tri = clip_first_tri;
-   clipper->stage.flush = clip_flush;
-   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
-   clipper->stage.destroy = clip_destroy;
-
-   clipper->plane = draw->plane;
-
-   return &clipper->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_cull.c b/src/gallium/auxiliary/draw/draw_cull.c
deleted file mode 100644 (file)
index 8177b0a..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * \brief  Drawing stage for polygon culling
- */
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "draw_private.h"
-
-
-struct cull_stage {
-   struct draw_stage stage;
-   unsigned winding;  /**< which winding(s) to cull (one of PIPE_WINDING_x) */
-};
-
-
-static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
-{
-   return (struct cull_stage *)stage;
-}
-
-
-
-
-static void cull_tri( struct draw_stage *stage,
-                     struct prim_header *header )
-{
-   /* Window coords: */
-   const float *v0 = header->v[0]->data[0];
-   const float *v1 = header->v[1]->data[0];
-   const float *v2 = header->v[2]->data[0];
-
-   /* edge vectors e = v0 - v2, f = v1 - v2 */
-   const float ex = v0[0] - v2[0];
-   const float ey = v0[1] - v2[1];
-   const float fx = v1[0] - v2[0];
-   const float fy = v1[1] - v2[1];
-   
-   /* det = cross(e,f).z */
-   header->det = ex * fy - ey * fx;
-
-   if (header->det != 0) {
-      /* if (det < 0 then Z points toward camera and triangle is 
-       * counter-clockwise winding.
-       */
-      unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
-
-      if ((winding & cull_stage(stage)->winding) == 0) {
-         /* triangle is not culled, pass to next stage */
-        stage->next->tri( stage->next, header );
-      }
-   }
-}
-
-static void cull_first_tri( struct draw_stage *stage, 
-                           struct prim_header *header )
-{
-   struct cull_stage *cull = cull_stage(stage);
-
-   cull->winding = stage->draw->rasterizer->cull_mode;
-
-   stage->tri = cull_tri;
-   stage->tri( stage, header );
-}
-
-
-
-static void cull_line( struct draw_stage *stage,
-                      struct prim_header *header )
-{
-   stage->next->line( stage->next, header );
-}
-
-
-static void cull_point( struct draw_stage *stage,
-                       struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void cull_flush( struct draw_stage *stage, unsigned flags )
-{
-   stage->tri = cull_first_tri;
-   stage->next->flush( stage->next, flags );
-}
-
-static void cull_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void cull_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create a new polygon culling stage.
- */
-struct draw_stage *draw_cull_stage( struct draw_context *draw )
-{
-   struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
-
-   draw_alloc_temp_verts( &cull->stage, 0 );
-
-   cull->stage.draw = draw;
-   cull->stage.next = NULL;
-   cull->stage.point = cull_point;
-   cull->stage.line = cull_line;
-   cull->stage.tri = cull_first_tri;
-   cull->stage.flush = cull_flush;
-   cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
-   cull->stage.destroy = cull_destroy;
-
-   return &cull->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_flatshade.c b/src/gallium/auxiliary/draw/draw_flatshade.c
deleted file mode 100644 (file)
index 54baa1f..0000000
+++ /dev/null
@@ -1,248 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_vs.h"
-
-
-/** subclass of draw_stage */
-struct flat_stage
-{
-   struct draw_stage stage;
-
-   uint num_color_attribs;
-   uint color_attribs[4];  /* front/back primary/secondary colors */
-};
-
-
-static INLINE struct flat_stage *
-flat_stage(struct draw_stage *stage)
-{
-   return (struct flat_stage *) stage;
-}
-
-
-/** Copy all the color attributes from 'src' vertex to 'dst' vertex */
-static INLINE void copy_colors( struct draw_stage *stage,
-                                struct vertex_header *dst,
-                                const struct vertex_header *src )
-{
-   const struct flat_stage *flat = flat_stage(stage);
-   uint i;
-   for (i = 0; i < flat->num_color_attribs; i++) {
-      const uint attr = flat->color_attribs[i];
-      COPY_4FV(dst->data[attr], src->data[attr]);
-   }
-}
-
-
-/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
-static INLINE void copy_colors2( struct draw_stage *stage,
-                                 struct vertex_header *dst0,
-                                 struct vertex_header *dst1,
-                                 const struct vertex_header *src )
-{
-   const struct flat_stage *flat = flat_stage(stage);
-   uint i;
-   for (i = 0; i < flat->num_color_attribs; i++) {
-      const uint attr = flat->color_attribs[i];
-      COPY_4FV(dst0->data[attr], src->data[attr]);
-      COPY_4FV(dst1->data[attr], src->data[attr]);
-   }
-}
-
-
-/**
- * Flatshade tri.  Required for clipping and when unfilled tris are
- * active, otherwise handled by hardware.
- */
-static void flatshade_tri_0( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   struct prim_header tmp;
-
-   tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
-   tmp.v[0] = header->v[0];
-   tmp.v[1] = dup_vert(stage, header->v[1], 0);
-   tmp.v[2] = dup_vert(stage, header->v[2], 1);
-
-   copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
-   
-   stage->next->tri( stage->next, &tmp );
-}
-
-
-static void flatshade_tri_2( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   struct prim_header tmp;
-
-   tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
-   tmp.v[0] = dup_vert(stage, header->v[0], 0);
-   tmp.v[1] = dup_vert(stage, header->v[1], 1);
-   tmp.v[2] = header->v[2];
-
-   copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
-   
-   stage->next->tri( stage->next, &tmp );
-}
-
-
-
-
-
-/**
- * Flatshade line.  Required for clipping.
- */
-static void flatshade_line_0( struct draw_stage *stage,
-                              struct prim_header *header )
-{
-   struct prim_header tmp;
-
-   tmp.v[0] = header->v[0];
-   tmp.v[1] = dup_vert(stage, header->v[1], 0);
-
-   copy_colors(stage, tmp.v[1], tmp.v[0]);
-   
-   stage->next->line( stage->next, &tmp );
-}
-
-static void flatshade_line_1( struct draw_stage *stage,
-                              struct prim_header *header )
-{
-   struct prim_header tmp;
-
-   tmp.v[0] = dup_vert(stage, header->v[0], 0);
-   tmp.v[1] = header->v[1];
-
-   copy_colors(stage, tmp.v[0], tmp.v[1]);
-   
-   stage->next->line( stage->next, &tmp );
-}
-
-
-/* Flatshade point -- passthrough.
- */
-static void flatshade_point( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void flatshade_init_state( struct draw_stage *stage )
-{
-   struct flat_stage *flat = flat_stage(stage);
-   const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
-   uint i;
-
-   /* Find which vertex shader outputs are colors, make a list */
-   flat->num_color_attribs = 0;
-   for (i = 0; i < vs->info.num_outputs; i++) {
-      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
-          vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         flat->color_attribs[flat->num_color_attribs++] = i;
-      }
-   }
-
-   /* Choose flatshade routine according to provoking vertex:
-    */
-   if (stage->draw->rasterizer->flatshade_first) {
-      stage->line = flatshade_line_0;
-      stage->tri = flatshade_tri_0;
-   }
-   else {
-      stage->line = flatshade_line_1;
-      stage->tri = flatshade_tri_2;
-   }
-}
-
-static void flatshade_first_tri( struct draw_stage *stage,
-                                struct prim_header *header )
-{
-   flatshade_init_state( stage );
-   stage->tri( stage, header );
-}
-
-static void flatshade_first_line( struct draw_stage *stage,
-                                 struct prim_header *header )
-{
-   flatshade_init_state( stage );
-   stage->line( stage, header );
-}
-
-
-static void flatshade_flush( struct draw_stage *stage, 
-                            unsigned flags )
-{
-   stage->tri = flatshade_first_tri;
-   stage->line = flatshade_first_line;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void flatshade_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void flatshade_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create flatshading drawing stage.
- */
-struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
-{
-   struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
-
-   draw_alloc_temp_verts( &flatshade->stage, 2 );
-
-   flatshade->stage.draw = draw;
-   flatshade->stage.next = NULL;
-   flatshade->stage.point = flatshade_point;
-   flatshade->stage.line = flatshade_first_line;
-   flatshade->stage.tri = flatshade_first_tri;
-   flatshade->stage.flush = flatshade_flush;
-   flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
-   flatshade->stage.destroy = flatshade_destroy;
-
-   return &flatshade->stage;
-}
-
-
diff --git a/src/gallium/auxiliary/draw/draw_offset.c b/src/gallium/auxiliary/draw/draw_offset.c
deleted file mode 100644 (file)
index dbc676d..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * \brief  polygon offset state
- *
- * \author  Keith Whitwell <keith@tungstengraphics.com>
- * \author  Brian Paul
- */
-
-#include "pipe/p_util.h"
-#include "draw_private.h"
-
-
-
-struct offset_stage {
-   struct draw_stage stage;
-
-   float scale;
-   float units;
-};
-
-
-
-static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
-{
-   return (struct offset_stage *) stage;
-}
-
-
-
-
-
-/**
- * Offset tri Z.  Some hardware can handle this, but not usually when
- * doing unfilled rendering.
- */
-static void do_offset_tri( struct draw_stage *stage,
-                          struct prim_header *header )
-{
-   struct offset_stage *offset = offset_stage(stage);   
-   float inv_det = 1.0f / header->det;
-
-   /* Window coords:
-    */
-   float *v0 = header->v[0]->data[0];
-   float *v1 = header->v[1]->data[0];
-   float *v2 = header->v[2]->data[0];
-
-   /* edge vectors e = v0 - v2, f = v1 - v2 */
-   float ex = v0[0] - v2[0];
-   float ey = v0[1] - v2[1];
-   float ez = v0[2] - v2[2];
-   float fx = v1[0] - v2[0];
-   float fy = v1[1] - v2[1];
-   float fz = v1[2] - v2[2];
-
-   /* (a,b) = cross(e,f).xy */
-   float a = ey*fz - ez*fy;
-   float b = ez*fx - ex*fz;
-
-   float dzdx = FABSF(a * inv_det);
-   float dzdy = FABSF(b * inv_det);
-
-   float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale;
-
-   /*
-    * Note: we're applying the offset and clamping per-vertex.
-    * Ideally, the offset is applied per-fragment prior to fragment shading.
-    */
-   v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f);
-   v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f);
-   v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f);
-
-   stage->next->tri( stage->next, header );
-}
-
-
-static void offset_tri( struct draw_stage *stage,
-                       struct prim_header *header )
-{
-   struct prim_header tmp;
-
-   tmp.det = header->det;
-   tmp.edgeflags = header->edgeflags;
-   tmp.v[0] = dup_vert(stage, header->v[0], 0);
-   tmp.v[1] = dup_vert(stage, header->v[1], 1);
-   tmp.v[2] = dup_vert(stage, header->v[2], 2);
-
-   do_offset_tri( stage, &tmp );
-}
-
-
-static void offset_first_tri( struct draw_stage *stage, 
-                             struct prim_header *header )
-{
-   struct offset_stage *offset = offset_stage(stage);
-   float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
-
-   offset->units = stage->draw->rasterizer->offset_units * mrd;
-   offset->scale = stage->draw->rasterizer->offset_scale;
-
-   stage->tri = offset_tri;
-   stage->tri( stage, header );
-}
-
-
-static void offset_line( struct draw_stage *stage,
-                        struct prim_header *header )
-{
-   stage->next->line( stage->next, header );
-}
-
-
-static void offset_point( struct draw_stage *stage,
-                         struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void offset_flush( struct draw_stage *stage,
-                         unsigned flags )
-{
-   stage->tri = offset_first_tri;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void offset_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void offset_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create polygon offset drawing stage.
- */
-struct draw_stage *draw_offset_stage( struct draw_context *draw )
-{
-   struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
-
-   draw_alloc_temp_verts( &offset->stage, 3 );
-
-   offset->stage.draw = draw;
-   offset->stage.next = NULL;
-   offset->stage.point = offset_point;
-   offset->stage.line = offset_line;
-   offset->stage.tri = offset_first_tri;
-   offset->stage.flush = offset_flush;
-   offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
-   offset->stage.destroy = offset_destroy;
-
-   return &offset->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aaline.c b/src/gallium/auxiliary/draw/draw_pipe_aaline.c
new file mode 100644 (file)
index 0000000..e8d2a45
--- /dev/null
@@ -0,0 +1,859 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * AA line stage:  AA lines are converted to texture mapped triangles.
+ *
+ * Authors:  Brian Paul
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "tgsi/util/tgsi_transform.h"
+#include "tgsi/util/tgsi_dump.h"
+
+#include "draw_context.h"
+#include "draw_private.h"
+
+
+/**
+ * Max texture level for the alpha texture used for antialiasing
+ */
+#define MAX_TEXTURE_LEVEL  5   /* 32 x 32 */
+
+
+/**
+ * Subclass of pipe_shader_state to carry extra fragment shader info.
+ */
+struct aaline_fragment_shader
+{
+   struct pipe_shader_state state;
+   void *driver_fs;
+   void *aaline_fs;
+   void *aapoint_fs; /* not yet */
+   void *sprite_fs; /* not yet */
+   uint sampler_unit;
+   int generic_attrib;  /**< texcoord/generic used for texture */
+};
+
+
+/**
+ * Subclass of draw_stage
+ */
+struct aaline_stage
+{
+   struct draw_stage stage;
+
+   float half_line_width;
+
+   /** For AA lines, this is the vertex attrib slot for the new texcoords */
+   uint tex_slot;
+
+   void *sampler_cso;
+   struct pipe_texture *texture;
+   uint num_samplers;
+   uint num_textures;
+
+
+   /*
+    * Currently bound state
+    */
+   struct aaline_fragment_shader *fs;
+   struct {
+      void *sampler[PIPE_MAX_SAMPLERS];
+      struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+   } state;
+
+   /*
+    * Driver interface/override functions
+    */
+   void * (*driver_create_fs_state)(struct pipe_context *,
+                                    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 *, unsigned,
+                                      void **);
+   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
+                                       struct pipe_texture **);
+
+   struct pipe_context *pipe;
+};
+
+
+
+/**
+ * Subclass of tgsi_transform_context, used for transforming the
+ * user's fragment shader to add the special AA instructions.
+ */
+struct aa_transform_context {
+   struct tgsi_transform_context base;
+   uint tempsUsed;  /**< bitmask */
+   int colorOutput; /**< which output is the primary color */
+   uint samplersUsed;  /**< bitfield of samplers used */
+   int freeSampler;  /** an available sampler for the pstipple */
+   int maxInput, maxGeneric;  /**< max input index found */
+   int colorTemp, texTemp;  /**< temp registers */
+   boolean firstInstruction;
+};
+
+
+/**
+ * TGSI declaration transform callback.
+ * Look for a free sampler, 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;
+
+   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
+       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
+       decl->Semantic.SemanticIndex == 0) {
+      aactx->colorOutput = decl->u.DeclarationRange.First;
+   }
+   else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         aactx->samplersUsed |= 1 << i;
+      }
+   }
+   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+      if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
+         aactx->maxInput = decl->u.DeclarationRange.Last;
+      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
+           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
+         aactx->maxGeneric = decl->Semantic.SemanticIndex;
+      }
+   }
+   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         aactx->tempsUsed |= (1 << i);
+      }
+   }
+
+   ctx->emit_declaration(ctx, decl);
+}
+
+
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+   int i;
+   for (i = 0; i < 32; i++) {
+      if ((bitfield & (1 << i)) == 0)
+         return i;
+   }
+   return -1;
+}
+
+
+/**
+ * TGSI instruction transform callback.
+ * Replace writes to result.color w/ a temp reg.
+ * Upon END instruction, insert texture sampling code for antialiasing.
+ */
+static void
+aa_transform_inst(struct tgsi_transform_context *ctx,
+                  struct tgsi_full_instruction *inst)
+{
+   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
+
+   if (aactx->firstInstruction) {
+      /* emit our new declarations before the first instruction */
+
+      struct tgsi_full_declaration decl;
+      uint i;
+
+      /* find free sampler */
+      aactx->freeSampler = free_bit(aactx->samplersUsed);
+      if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
+         aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
+      /* find two free temp regs */
+      for (i = 0; i < 32; 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
+               break;
+         }
+      }
+      assert(aactx->colorTemp >= 0);
+      assert(aactx->texTemp >= 0);
+
+      /* declare new generic input/texcoord */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_INPUT;
+      decl.Declaration.Semantic = 1;
+      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
+      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
+      decl.Declaration.Interpolate = 1;
+      /* XXX this could be linear... */
+      decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = aactx->maxInput + 1;
+      ctx->emit_declaration(ctx, &decl);
+
+      /* declare new sampler */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_SAMPLER;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = aactx->freeSampler;
+      ctx->emit_declaration(ctx, &decl);
+
+      /* declare new temp regs */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = aactx->texTemp;
+      ctx->emit_declaration(ctx, &decl);
+
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = aactx->colorTemp;
+      ctx->emit_declaration(ctx, &decl);
+
+      aactx->firstInstruction = FALSE;
+   }
+
+   if (inst->Instruction.Opcode == TGSI_OPCODE_END &&
+       aactx->colorOutput != -1) {
+      struct tgsi_full_instruction newInst;
+
+      /* TEX */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = aactx->texTemp;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->maxInput + 1;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->freeSampler;
+
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* MOV rgb */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* MUL alpha */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->texTemp;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* END */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_END;
+      newInst.Instruction.NumDstRegs = 0;
+      newInst.Instruction.NumSrcRegs = 0;
+      ctx->emit_instruction(ctx, &newInst);
+   }
+   else {
+      /* Not an END instruction.
+       * Look for writes to result.color and replace with colorTemp reg.
+       */
+      uint i;
+
+      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
+             dst->DstRegister.Index == aactx->colorOutput) {
+            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
+            dst->DstRegister.Index = aactx->colorTemp;
+         }
+      }
+
+      ctx->emit_instruction(ctx, inst);
+   }
+}
+
+
+/**
+ * Generate the frag shader we'll use for drawing AA lines.
+ * This will be the user's shader plus some texture/modulate instructions.
+ */
+static void
+generate_aaline_fs(struct aaline_stage *aaline)
+{
+   const struct pipe_shader_state *orig_fs = &aaline->fs->state;
+   //struct draw_context *draw = aaline->stage.draw;
+   struct pipe_shader_state aaline_fs;
+   struct aa_transform_context transform;
+
+#define MAX 1000
+
+   aaline_fs = *orig_fs; /* copy to init */
+   aaline_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
+
+   memset(&transform, 0, sizeof(transform));
+   transform.colorOutput = -1;
+   transform.maxInput = -1;
+   transform.maxGeneric = -1;
+   transform.colorTemp = -1;
+   transform.texTemp = -1;
+   transform.firstInstruction = TRUE;
+   transform.base.transform_instruction = aa_transform_inst;
+   transform.base.transform_declaration = aa_transform_decl;
+
+   tgsi_transform_shader(orig_fs->tokens,
+                         (struct tgsi_token *) aaline_fs.tokens,
+                         MAX, &transform.base);
+
+#if 0 /* DEBUG */
+   tgsi_dump(orig_fs->tokens, 0);
+   tgsi_dump(aaline_fs.tokens, 0);
+#endif
+
+   aaline->fs->sampler_unit = transform.freeSampler;
+
+   aaline->fs->aaline_fs
+      = aaline->driver_create_fs_state(aaline->pipe, &aaline_fs);
+
+   aaline->fs->generic_attrib = transform.maxGeneric + 1;
+}
+
+
+/**
+ * Create the texture map we'll use for antialiasing the lines.
+ */
+static void
+aaline_create_texture(struct aaline_stage *aaline)
+{
+   struct pipe_context *pipe = aaline->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_texture texTemp;
+   uint level;
+
+   memset(&texTemp, 0, sizeof(texTemp));
+   texTemp.target = PIPE_TEXTURE_2D;
+   texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */
+   texTemp.last_level = MAX_TEXTURE_LEVEL;
+   texTemp.width[0] = 1 << MAX_TEXTURE_LEVEL;
+   texTemp.height[0] = 1 << MAX_TEXTURE_LEVEL;
+   texTemp.depth[0] = 1;
+   texTemp.cpp = 1;
+
+   aaline->texture = screen->texture_create(screen, &texTemp);
+
+   /* 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.
+    */
+   for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
+      struct pipe_surface *surface;
+      const uint size = aaline->texture->width[level];
+      ubyte *data;
+      uint i, j;
+
+      assert(aaline->texture->width[level] == aaline->texture->height[level]);
+
+      surface = screen->get_tex_surface(screen, aaline->texture, 0, level, 0);
+      data = pipe_surface_map(surface);
+
+      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 = 0;
+            }
+            else {
+               d = 255;
+            }
+            data[i * surface->pitch + j] = d;
+         }
+      }
+
+      /* unmap */
+      pipe_surface_unmap(surface);
+      pipe_surface_reference(&surface, NULL);
+      pipe->texture_update(pipe, aaline->texture, 0, (1 << level));
+   }
+}
+
+
+/**
+ * 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 void
+aaline_create_sampler(struct aaline_stage *aaline)
+{
+   struct pipe_sampler_state sampler;
+   struct pipe_context *pipe = aaline->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);
+}
+
+
+/**
+ * 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.
+ */
+static void
+bind_aaline_fragment_shader(struct aaline_stage *aaline)
+{
+   if (!aaline->fs->aaline_fs) {
+      generate_aaline_fs(aaline);
+   }
+   aaline->driver_bind_fs_state(aaline->pipe, aaline->fs->aaline_fs);
+}
+
+
+
+static INLINE struct aaline_stage *
+aaline_stage( struct draw_stage *stage )
+{
+   return (struct aaline_stage *) stage;
+}
+
+
+static void
+passthrough_point(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->point(stage->next, header);
+}
+
+
+static void
+passthrough_tri(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+/**
+ * Draw a wide line by drawing a quad, using geometry which will
+ * fullfill GL's antialiased line requirements.
+ */
+static void
+aaline_line(struct draw_stage *stage, struct prim_header *header)
+{
+   const struct aaline_stage *aaline = aaline_stage(stage);
+   const float half_width = aaline->half_line_width;
+   struct prim_header tri;
+   struct vertex_header *v[8];
+   uint texPos = aaline->tex_slot;
+   float *pos, *tex;
+   float dx = header->v[1]->data[0][0] - header->v[0]->data[0][0];
+   float dy = header->v[1]->data[0][1] - header->v[0]->data[0][1];
+   double a = atan2(dy, dx);
+   float c_a = (float) cos(a), s_a = (float) sin(a);
+   uint i;
+
+   /* XXX the ends of lines aren't quite perfect yet, but probably passable */
+   dx = 0.5F * half_width;
+   dy = half_width;
+
+   /* allocate/dup new verts */
+   for (i = 0; i < 8; i++) {
+      v[i] = dup_vert(stage, header->v[i/4], i);
+   }
+
+   /*
+    * Quad strip for line from v0 to v1 (*=endpoints):
+    *
+    *  1   3                     5   7
+    *  +---+---------------------+---+
+    *  |                             |
+    *  | *v0                     v1* |
+    *  |                             |
+    *  +---+---------------------+---+
+    *  0   2                     4   6
+    */
+
+   /* new verts */
+   pos = v[0]->data[0];
+   pos[0] += (-dx * c_a -  dy * s_a);
+   pos[1] += (-dx * s_a +  dy * c_a);
+
+   pos = v[1]->data[0];
+   pos[0] += (-dx * c_a - -dy * s_a);
+   pos[1] += (-dx * s_a + -dy * c_a);
+
+   pos = v[2]->data[0];
+   pos[0] += ( dx * c_a -  dy * s_a);
+   pos[1] += ( dx * s_a +  dy * c_a);
+
+   pos = v[3]->data[0];
+   pos[0] += ( dx * c_a - -dy * s_a);
+   pos[1] += ( dx * s_a + -dy * c_a);
+
+   pos = v[4]->data[0];
+   pos[0] += (-dx * c_a -  dy * s_a);
+   pos[1] += (-dx * s_a +  dy * c_a);
+
+   pos = v[5]->data[0];
+   pos[0] += (-dx * c_a - -dy * s_a);
+   pos[1] += (-dx * s_a + -dy * c_a);
+
+   pos = v[6]->data[0];
+   pos[0] += ( dx * c_a -  dy * s_a);
+   pos[1] += ( dx * s_a +  dy * c_a);
+
+   pos = v[7]->data[0];
+   pos[0] += ( dx * c_a - -dy * s_a);
+   pos[1] += ( dx * s_a + -dy * 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[3]->data[texPos];
+   ASSIGN_4V(tex, .5, 1, 0, 1);
+
+   tex = v[4]->data[texPos];
+   ASSIGN_4V(tex, .5, 0, 0, 1);
+
+   tex = v[5]->data[texPos];
+   ASSIGN_4V(tex, .5, 1, 0, 1);
+
+   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 );
+}
+
+
+static void
+aaline_first_line(struct draw_stage *stage, struct prim_header *header)
+{
+   auto struct aaline_stage *aaline = aaline_stage(stage);
+   struct draw_context *draw = stage->draw;
+   struct pipe_context *pipe = aaline->pipe;
+   uint num_samplers;
+
+   assert(draw->rasterizer->line_smooth);
+
+   if (draw->rasterizer->line_width <= 3.0)
+      aaline->half_line_width = 1.5f;
+   else
+      aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
+
+   /*
+    * Bind (generate) our fragprog, sampler and texture
+    */
+   bind_aaline_fragment_shader(aaline);
+
+   /* update vertex attrib info */
+   aaline->tex_slot = draw->num_vs_outputs;
+   assert(aaline->tex_slot > 0); /* output[0] is vertex pos */
+
+   /* advertise the extra post-transformed vertex attribute */
+   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+   draw->extra_vp_outputs.semantic_index = aaline->fs->generic_attrib;
+   draw->extra_vp_outputs.slot = aaline->tex_slot;
+
+   /* how many samplers? */
+   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
+   num_samplers = MAX2(aaline->num_textures, aaline->num_samplers);
+   num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
+
+   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
+   pipe_texture_reference(&aaline->state.texture[aaline->fs->sampler_unit],
+                          aaline->texture);
+
+   aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
+   aaline->driver_set_sampler_textures(pipe, num_samplers, aaline->state.texture);
+
+   /* now really draw first line */
+   stage->line = aaline_line;
+   stage->line(stage, header);
+}
+
+
+static void
+aaline_flush(struct draw_stage *stage, unsigned flags)
+{
+   struct draw_context *draw = stage->draw;
+   struct aaline_stage *aaline = aaline_stage(stage);
+   struct pipe_context *pipe = aaline->pipe;
+
+   stage->line = aaline_first_line;
+   stage->next->flush( stage->next, flags );
+
+   /* restore original frag shader */
+   aaline->driver_bind_fs_state(pipe, aaline->fs->driver_fs);
+
+   /* XXX restore original texture, sampler state */
+   aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
+                                      aaline->state.sampler);
+   aaline->driver_set_sampler_textures(pipe, aaline->num_textures,
+                                       aaline->state.texture);
+
+   draw->extra_vp_outputs.slot = 0;
+}
+
+
+static void
+aaline_reset_stipple_counter(struct draw_stage *stage)
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void
+aaline_destroy(struct draw_stage *stage)
+{
+   struct aaline_stage *aaline = aaline_stage(stage);
+
+   aaline->pipe->delete_sampler_state(aaline->pipe, aaline->sampler_cso);
+
+   pipe_texture_release(&aaline->texture);
+
+   draw_free_temp_verts( stage );
+
+   FREE( stage );
+}
+
+
+static struct aaline_stage *
+draw_aaline_stage(struct draw_context *draw)
+{
+   struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
+
+   draw_alloc_temp_verts( &aaline->stage, 8 );
+
+   aaline->stage.draw = draw;
+   aaline->stage.next = NULL;
+   aaline->stage.point = passthrough_point;
+   aaline->stage.line = aaline_first_line;
+   aaline->stage.tri = passthrough_tri;
+   aaline->stage.flush = aaline_flush;
+   aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter;
+   aaline->stage.destroy = aaline_destroy;
+
+   return aaline;
+}
+
+
+static struct aaline_stage *
+aaline_stage_from_pipe(struct pipe_context *pipe)
+{
+   struct draw_context *draw = (struct draw_context *) pipe->draw;
+   return aaline_stage(draw->pipeline.aaline);
+}
+
+
+/**
+ * This function overrides the driver's create_fs_state() function and
+ * will typically be called by the state tracker.
+ */
+static void *
+aaline_create_fs_state(struct pipe_context *pipe,
+                       const struct pipe_shader_state *fs)
+{
+   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
+   struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
+
+   if (aafs) {
+      aafs->state = *fs;
+
+      /* pass-through */
+      aafs->driver_fs = aaline->driver_create_fs_state(aaline->pipe, fs);
+   }
+
+   return aafs;
+}
+
+
+static void
+aaline_bind_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
+   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
+   /* save current */
+   aaline->fs = aafs;
+   /* pass-through */
+   aaline->driver_bind_fs_state(aaline->pipe,
+                                (aafs ? aafs->driver_fs : NULL));
+}
+
+
+static void
+aaline_delete_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
+   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
+   /* pass-through */
+   aaline->driver_delete_fs_state(aaline->pipe, aafs->driver_fs);
+   FREE(aafs);
+}
+
+
+static void
+aaline_bind_sampler_states(struct pipe_context *pipe,
+                           unsigned num, void **sampler)
+{
+   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
+   /* save current */
+   memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
+   aaline->num_samplers = num;
+   /* pass-through */
+   aaline->driver_bind_sampler_states(aaline->pipe, num, sampler);
+}
+
+
+static void
+aaline_set_sampler_textures(struct pipe_context *pipe,
+                            unsigned num, struct pipe_texture **texture)
+{
+   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
+   uint i;
+
+   /* save current */
+   for (i = 0; i < num; i++) {
+      pipe_texture_reference(&aaline->state.texture[i], texture[i]);
+   }
+   aaline->num_textures = num;
+
+   /* pass-through */
+   aaline->driver_set_sampler_textures(aaline->pipe, num, texture);
+}
+
+
+/**
+ * Called by drivers that want to install this AA line prim stage
+ * into the draw module's pipeline.  This will not be used if the
+ * hardware has native support for AA lines.
+ */
+void
+draw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
+{
+   struct aaline_stage *aaline;
+
+   pipe->draw = (void *) draw;
+
+   /*
+    * Create / install AA line drawing / prim stage
+    */
+   aaline = draw_aaline_stage( draw );
+   assert(aaline);
+   draw->pipeline.aaline = &aaline->stage;
+
+   aaline->pipe = pipe;
+
+   /* create special texture, sampler state */
+   aaline_create_texture(aaline);
+   aaline_create_sampler(aaline);
+
+   /* save original driver functions */
+   aaline->driver_create_fs_state = pipe->create_fs_state;
+   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_textures = pipe->set_sampler_textures;
+
+   /* 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_textures = aaline_set_sampler_textures;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_aapoint.c b/src/gallium/auxiliary/draw/draw_pipe_aapoint.c
new file mode 100644 (file)
index 0000000..e84d380
--- /dev/null
@@ -0,0 +1,846 @@
+/**************************************************************************
+ * 
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * AA point stage:  AA points are converted to quads and rendered with a
+ * special fragment shader.  Another approach would be to use a texture
+ * map image of a point, but experiments indicate the quality isn't nearly
+ * as good as this approach.
+ *
+ * Note: this looks a lot like draw_aaline.c but there's actually little
+ * if any code that can be shared.
+ *
+ * Authors:  Brian Paul
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "tgsi/util/tgsi_transform.h"
+#include "tgsi/util/tgsi_dump.h"
+
+#include "draw_context.h"
+#include "draw_vs.h"
+
+
+/*
+ * Enabling NORMALIZE might give _slightly_ better results.
+ * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or
+ * d=x*x+y*y.  Since we're working with a unit circle, the later seems
+ * close enough and saves some costly instructions.
+ */
+#define NORMALIZE 0
+
+
+/**
+ * Subclass of pipe_shader_state to carry extra fragment shader info.
+ */
+struct aapoint_fragment_shader
+{
+   struct pipe_shader_state state;
+   void *driver_fs;   /**< the regular shader */
+   void *aapoint_fs;  /**< the aa point-augmented shader */
+   int generic_attrib; /**< The generic input attrib/texcoord we'll use */
+};
+
+
+/**
+ * Subclass of draw_stage
+ */
+struct aapoint_stage
+{
+   struct draw_stage stage;
+
+   int psize_slot;
+   float radius;
+
+   /** this is the vertex attrib slot for the new texcoords */
+   uint tex_slot;
+
+   /*
+    * Currently bound state
+    */
+   struct aapoint_fragment_shader *fs;
+
+   /*
+    * Driver interface/override functions
+    */
+   void * (*driver_create_fs_state)(struct pipe_context *,
+                                    const struct pipe_shader_state *);
+   void (*driver_bind_fs_state)(struct pipe_context *, void *);
+   void (*driver_delete_fs_state)(struct pipe_context *, void *);
+
+   struct pipe_context *pipe;
+};
+
+
+
+/**
+ * Subclass of tgsi_transform_context, used for transforming the
+ * user's fragment shader to add the special AA instructions.
+ */
+struct aa_transform_context {
+   struct tgsi_transform_context base;
+   uint tempsUsed;  /**< bitmask */
+   int colorOutput; /**< which output is the primary color */
+   int maxInput, maxGeneric;  /**< max input index found */
+   int tmp0, colorTemp;  /**< temp registers */
+   boolean firstInstruction;
+};
+
+
+/**
+ * TGSI declaration transform callback.
+ * Look for two free temp regs and available input reg for new texcoords.
+ */
+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;
+
+   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
+       decl->Semantic.SemanticName == TGSI_SEMANTIC_COLOR &&
+       decl->Semantic.SemanticIndex == 0) {
+      aactx->colorOutput = decl->u.DeclarationRange.First;
+   }
+   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+      if ((int) decl->u.DeclarationRange.Last > aactx->maxInput)
+         aactx->maxInput = decl->u.DeclarationRange.Last;
+      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_GENERIC &&
+           (int) decl->Semantic.SemanticIndex > aactx->maxGeneric) {
+         aactx->maxGeneric = decl->Semantic.SemanticIndex;
+      }
+   }
+   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         aactx->tempsUsed |= (1 << i);
+      }
+   }
+
+   ctx->emit_declaration(ctx, decl);
+}
+
+
+/**
+ * TGSI instruction transform callback.
+ * Replace writes to result.color w/ a temp reg.
+ * Upon END instruction, insert texture sampling code for antialiasing.
+ */
+static void
+aa_transform_inst(struct tgsi_transform_context *ctx,
+                  struct tgsi_full_instruction *inst)
+{
+   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
+   struct tgsi_full_instruction newInst;
+
+   if (aactx->firstInstruction) {
+      /* emit our new declarations before the first instruction */
+
+      struct tgsi_full_declaration decl;
+      const int texInput = aactx->maxInput + 1;
+      int tmp0;
+      uint i;
+
+      /* find two free temp regs */
+      for (i = 0; i < 32; i++) {
+         if ((aactx->tempsUsed & (1 << i)) == 0) {
+            /* found a free temp */
+            if (aactx->tmp0 < 0)
+               aactx->tmp0 = i;
+            else if (aactx->colorTemp < 0)
+               aactx->colorTemp = i;
+            else
+               break;
+         }
+      }
+
+      assert(aactx->colorTemp != aactx->tmp0);
+
+      tmp0 = aactx->tmp0;
+
+      /* declare new generic input/texcoord */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_INPUT;
+      decl.Declaration.Semantic = 1;
+      decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
+      decl.Semantic.SemanticIndex = aactx->maxGeneric + 1;
+      decl.Declaration.Interpolate = 1;
+      /* XXX this could be linear... */
+      decl.Interpolation.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = texInput;
+      ctx->emit_declaration(ctx, &decl);
+
+      /* declare new temp regs */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = tmp0;
+      ctx->emit_declaration(ctx, &decl);
+
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = aactx->colorTemp;
+      ctx->emit_declaration(ctx, &decl);
+
+      aactx->firstInstruction = FALSE;
+
+
+      /*
+       * Emit code to compute fragment coverage, kill if outside point radius
+       *
+       * Temp reg0 usage:
+       *  t0.x = distance of fragment from center point
+       *  t0.y = boolean, is t0.x > 1.0, also misc temp usage
+       *  t0.z = temporary for computing 1/(1-k) value
+       *  t0.w = final coverage value
+       */
+
+      /* MUL t0.xy, tex, tex;  # compute x^2, y^2 */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XY;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
+      ctx->emit_instruction(ctx, &newInst);
+
+#if NORMALIZE  /* OPTIONAL normalization of length */
+      /* RSQ t0.x, t0.x; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* RCP t0.x, t0.x; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_X;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      ctx->emit_instruction(ctx, &newInst);
+#endif
+
+      /* SGT t0.y, t0.xxxx, t0.wwww;  # bool b = d > 1 (NOTE t0.w == 1) */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* KILP -t0.yyyy;   # if b, KILL */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
+      newInst.Instruction.NumDstRegs = 0;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+      ctx->emit_instruction(ctx, &newInst);
+
+
+      /* compute coverage factor = (1-d)/(1-k) */
+
+      /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* RCP t0.z, t0.z;  # t0.z = 1 / m */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Z;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Z;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* SUB t0.y, 1, t0.x;  # d = 1 - d */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_Z;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_Y;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_Z;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* CMP t0.w, -t0.y, tex.w, t0.w;
+       *  # if -t0.y < 0 then
+       *       t0.w = 1
+       *    else
+       *       t0.w = t0.w
+       */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = tmp0;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Instruction.NumSrcRegs = 3;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_Y;
+      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = texInput;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[1].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[2].SrcRegister.Index = tmp0;
+      newInst.FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_W;
+      newInst.FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
+      ctx->emit_instruction(ctx, &newInst);
+
+   }
+
+   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
+      /* add alpha modulation code at tail of program */
+
+      /* MOV result.color.xyz, colorTemp; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_XYZ;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* MUL result.color.w, colorTemp, tmp0.w; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
+      newInst.FullDstRegisters[0].DstRegister.Index = aactx->colorOutput;
+      newInst.FullDstRegisters[0].DstRegister.WriteMask = TGSI_WRITEMASK_W;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = aactx->colorTemp;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = aactx->tmp0;
+      ctx->emit_instruction(ctx, &newInst);
+   }
+   else {
+      /* Not an END instruction.
+       * Look for writes to result.color and replace with colorTemp reg.
+       */
+      uint i;
+
+      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+         struct tgsi_full_dst_register *dst = &inst->FullDstRegisters[i];
+         if (dst->DstRegister.File == TGSI_FILE_OUTPUT &&
+             dst->DstRegister.Index == aactx->colorOutput) {
+            dst->DstRegister.File = TGSI_FILE_TEMPORARY;
+            dst->DstRegister.Index = aactx->colorTemp;
+         }
+      }
+   }
+
+   ctx->emit_instruction(ctx, inst);
+}
+
+
+/**
+ * Generate the frag shader we'll use for drawing AA lines.
+ * This will be the user's shader plus some texture/modulate instructions.
+ */
+static void
+generate_aapoint_fs(struct aapoint_stage *aapoint)
+{
+   const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
+   struct pipe_shader_state aapoint_fs;
+   struct aa_transform_context transform;
+
+#define MAX 1000
+
+   aapoint_fs = *orig_fs; /* copy to init */
+   aapoint_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
+
+   memset(&transform, 0, sizeof(transform));
+   transform.colorOutput = -1;
+   transform.maxInput = -1;
+   transform.maxGeneric = -1;
+   transform.colorTemp = -1;
+   transform.tmp0 = -1;
+   transform.firstInstruction = TRUE;
+   transform.base.transform_instruction = aa_transform_inst;
+   transform.base.transform_declaration = aa_transform_decl;
+
+   tgsi_transform_shader(orig_fs->tokens,
+                         (struct tgsi_token *) aapoint_fs.tokens,
+                         MAX, &transform.base);
+
+#if 0 /* DEBUG */
+   printf("draw_aapoint, orig shader:\n");
+   tgsi_dump(orig_fs->tokens, 0);
+   printf("draw_aapoint, new shader:\n");
+   tgsi_dump(aapoint_fs.tokens, 0);
+#endif
+
+   aapoint->fs->aapoint_fs
+      = aapoint->driver_create_fs_state(aapoint->pipe, &aapoint_fs);
+
+   aapoint->fs->generic_attrib = transform.maxGeneric + 1;
+}
+
+
+/**
+ * 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.
+ */
+static void
+bind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
+{
+   if (!aapoint->fs->aapoint_fs) {
+      generate_aapoint_fs(aapoint);
+   }
+   aapoint->driver_bind_fs_state(aapoint->pipe, aapoint->fs->aapoint_fs);
+}
+
+
+
+static INLINE struct aapoint_stage *
+aapoint_stage( struct draw_stage *stage )
+{
+   return (struct aapoint_stage *) stage;
+}
+
+
+static void
+passthrough_line(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->line(stage->next, header);
+}
+
+
+static void
+passthrough_tri(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+/**
+ * Draw an AA point by drawing a quad.
+ */
+static void
+aapoint_point(struct draw_stage *stage, struct prim_header *header)
+{
+   const struct aapoint_stage *aapoint = aapoint_stage(stage);
+   struct prim_header tri;
+   struct vertex_header *v[4];
+   uint texPos = aapoint->tex_slot;
+   float radius, *pos, *tex;
+   uint i;
+   float k;
+
+   if (aapoint->psize_slot >= 0) {
+      radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0];
+   }
+   else {
+      radius = aapoint->radius;
+   }
+
+   /*
+    * Note: the texcoords (generic attrib, really) we use are special:
+    * The S and T components simply vary from -1 to +1.
+    * The R component is k, below.
+    * The Q component is 1.0 and will used as a handy constant in the
+    * fragment shader.
+    */
+
+   /*
+    * k is the threshold distance from the point's center at which
+    * we begin alpha attenuation (the coverage value).
+    * Operating within a unit circle, we'll compute the fragment's
+    * distance 'd' from the center point using the texcoords.
+    * IF d > 1.0 THEN
+    *    KILL fragment
+    * ELSE IF d > k THEN
+    *    compute coverage in [0,1] proportional to d in [k, 1].
+    * ELSE
+    *    coverage = 1.0;  // full coverage
+    * ENDIF
+    *
+    * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to
+    * avoid using IF/ELSE/ENDIF TGSI opcodes.
+    */
+
+#if !NORMALIZE
+   k = 1.0f / radius;
+   k = 1.0f - 2.0f * k + k * k;
+#else
+   k = 1.0f - 1.0f / radius;
+#endif
+
+   /* allocate/dup new verts */
+   for (i = 0; i < 4; i++) {
+      v[i] = dup_vert(stage, header->v[0], i);
+   }
+
+   /* new verts */
+   pos = v[0]->data[0];
+   pos[0] -= radius;
+   pos[1] -= radius;
+
+   pos = v[1]->data[0];
+   pos[0] += radius;
+   pos[1] -= radius;
+
+   pos = v[2]->data[0];
+   pos[0] += radius;
+   pos[1] += radius;
+
+   pos = v[3]->data[0];
+   pos[0] -= radius;
+   pos[1] += radius;
+
+   /* new texcoords */
+   tex = v[0]->data[texPos];
+   ASSIGN_4V(tex, -1, -1, k, 1);
+
+   tex = v[1]->data[texPos];
+   ASSIGN_4V(tex,  1, -1, k, 1);
+
+   tex = v[2]->data[texPos];
+   ASSIGN_4V(tex,  1,  1, k, 1);
+
+   tex = v[3]->data[texPos];
+   ASSIGN_4V(tex, -1,  1, k, 1);
+
+   /* emit 2 tris for the quad strip */
+   tri.v[0] = v[0];
+   tri.v[1] = v[1];
+   tri.v[2] = v[2];
+   stage->next->tri( stage->next, &tri );
+
+   tri.v[0] = v[0];
+   tri.v[1] = v[2];
+   tri.v[2] = v[3];
+   stage->next->tri( stage->next, &tri );
+}
+
+
+static void
+aapoint_first_point(struct draw_stage *stage, struct prim_header *header)
+{
+   auto struct aapoint_stage *aapoint = aapoint_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   assert(draw->rasterizer->point_smooth);
+
+   if (draw->rasterizer->point_size <= 2.0)
+      aapoint->radius = 1.0;
+   else
+      aapoint->radius = 0.5f * draw->rasterizer->point_size;
+
+   /*
+    * Bind (generate) our fragprog.
+    */
+   bind_aapoint_fragment_shader(aapoint);
+
+   /* update vertex attrib info */
+   aapoint->tex_slot = draw->num_vs_outputs;
+   assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
+
+   draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
+   draw->extra_vp_outputs.semantic_index = aapoint->fs->generic_attrib;
+   draw->extra_vp_outputs.slot = aapoint->tex_slot;
+
+   /* find psize slot in post-transform vertex */
+   aapoint->psize_slot = -1;
+   if (draw->rasterizer->point_size_per_vertex) {
+      /* find PSIZ vertex output */
+      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      uint i;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
+            aapoint->psize_slot = i;
+            break;
+         }
+      }
+   }
+
+   /* now really draw first line */
+   stage->point = aapoint_point;
+   stage->point(stage, header);
+}
+
+
+static void
+aapoint_flush(struct draw_stage *stage, unsigned flags)
+{
+   struct draw_context *draw = stage->draw;
+   struct aapoint_stage *aapoint = aapoint_stage(stage);
+   struct pipe_context *pipe = aapoint->pipe;
+
+   stage->point = aapoint_first_point;
+   stage->next->flush( stage->next, flags );
+
+   /* restore original frag shader */
+   aapoint->driver_bind_fs_state(pipe, aapoint->fs->driver_fs);
+
+   draw->extra_vp_outputs.slot = 0;
+}
+
+
+static void
+aapoint_reset_stipple_counter(struct draw_stage *stage)
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void
+aapoint_destroy(struct draw_stage *stage)
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+static struct aapoint_stage *
+draw_aapoint_stage(struct draw_context *draw)
+{
+   struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
+
+   draw_alloc_temp_verts( &aapoint->stage, 4 );
+
+   aapoint->stage.draw = draw;
+   aapoint->stage.next = NULL;
+   aapoint->stage.point = aapoint_first_point;
+   aapoint->stage.line = passthrough_line;
+   aapoint->stage.tri = passthrough_tri;
+   aapoint->stage.flush = aapoint_flush;
+   aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
+   aapoint->stage.destroy = aapoint_destroy;
+
+   return aapoint;
+}
+
+
+static struct aapoint_stage *
+aapoint_stage_from_pipe(struct pipe_context *pipe)
+{
+   struct draw_context *draw = (struct draw_context *) pipe->draw;
+   return aapoint_stage(draw->pipeline.aapoint);
+}
+
+
+/**
+ * This function overrides the driver's create_fs_state() function and
+ * will typically be called by the state tracker.
+ */
+static void *
+aapoint_create_fs_state(struct pipe_context *pipe,
+                       const struct pipe_shader_state *fs)
+{
+   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
+   struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
+
+   if (aafs) {
+      aafs->state = *fs;
+
+      /* pass-through */
+      aafs->driver_fs = aapoint->driver_create_fs_state(aapoint->pipe, fs);
+   }
+
+   return aafs;
+}
+
+
+static void
+aapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
+   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
+   /* save current */
+   aapoint->fs = aafs;
+   /* pass-through */
+   aapoint->driver_bind_fs_state(aapoint->pipe,
+                                 (aafs ? aafs->driver_fs : NULL));
+}
+
+
+static void
+aapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
+   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
+   /* pass-through */
+   aapoint->driver_delete_fs_state(aapoint->pipe, aafs->driver_fs);
+   FREE(aafs);
+}
+
+
+/**
+ * Called by drivers that want to install this AA point prim stage
+ * into the draw module's pipeline.  This will not be used if the
+ * hardware has native support for AA points.
+ */
+void
+draw_install_aapoint_stage(struct draw_context *draw,
+                           struct pipe_context *pipe)
+{
+   struct aapoint_stage *aapoint;
+
+   pipe->draw = (void *) draw;
+
+   /*
+    * Create / install AA point drawing / prim stage
+    */
+   aapoint = draw_aapoint_stage( draw );
+   assert(aapoint);
+   draw->pipeline.aapoint = &aapoint->stage;
+
+   aapoint->pipe = pipe;
+
+   /* save original driver functions */
+   aapoint->driver_create_fs_state = pipe->create_fs_state;
+   aapoint->driver_bind_fs_state = pipe->bind_fs_state;
+   aapoint->driver_delete_fs_state = pipe->delete_fs_state;
+
+   /* override the driver's functions */
+   pipe->create_fs_state = aapoint_create_fs_state;
+   pipe->bind_fs_state = aapoint_bind_fs_state;
+   pipe->delete_fs_state = aapoint_delete_fs_state;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
new file mode 100644 (file)
index 0000000..0ac3a24
--- /dev/null
@@ -0,0 +1,503 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Clipping stage
+ *
+ * \author  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "draw_context.h"
+#include "draw_vs.h"
+
+
+#ifndef IS_NEGATIVE
+#define IS_NEGATIVE(X) ((X) < 0.0)
+#endif
+
+#ifndef DIFFERENT_SIGNS
+#define DIFFERENT_SIGNS(x, y) ((x) * (y) <= 0.0F && (x) - (y) != 0.0F)
+#endif
+
+#ifndef MAX_CLIPPED_VERTICES
+#define MAX_CLIPPED_VERTICES ((2 * (6 + PIPE_MAX_CLIP_PLANES))+1)
+#endif
+
+
+
+struct clipper {
+   struct draw_stage stage;      /**< base class */
+
+   /* Basically duplicate some of the flatshading logic here:
+    */
+   boolean flat;
+   uint num_color_attribs;
+   uint color_attribs[4];  /* front/back primary/secondary colors */
+
+   float (*plane)[4];
+};
+
+
+/* This is a bit confusing:
+ */
+static INLINE struct clipper *clipper_stage( struct draw_stage *stage )
+{
+   return (struct clipper *)stage;
+}
+
+
+#define LINTERP(T, OUT, IN) ((OUT) + (T) * ((IN) - (OUT)))
+
+
+/* All attributes are float[4], so this is easy:
+ */
+static void interp_attr( float *fdst,
+                        float t,
+                        const float *fin,
+                        const float *fout )
+{  
+   fdst[0] = LINTERP( t, fout[0], fin[0] );
+   fdst[1] = LINTERP( t, fout[1], fin[1] );
+   fdst[2] = LINTERP( t, fout[2], fin[2] );
+   fdst[3] = LINTERP( t, fout[3], fin[3] );
+}
+
+static void copy_colors( struct draw_stage *stage,
+                        struct vertex_header *dst,
+                        const struct vertex_header *src )
+{
+   const struct clipper *clipper = clipper_stage(stage);
+   uint i;
+   for (i = 0; i < clipper->num_color_attribs; i++) {
+      const uint attr = clipper->color_attribs[i];
+      COPY_4FV(dst->data[attr], src->data[attr]);
+   }
+}
+
+
+
+/* Interpolate between two vertices to produce a third.  
+ */
+static void interp( const struct clipper *clip,
+                   struct vertex_header *dst,
+                   float t,
+                   const struct vertex_header *out, 
+                   const struct vertex_header *in )
+{
+   const unsigned nr_attrs = clip->stage.draw->num_vs_outputs;
+   unsigned j;
+
+   /* Vertex header.
+    */
+   {
+      dst->clipmask = 0;
+      dst->edgeflag = 0;
+      dst->pad = 0;
+      dst->vertex_id = UNDEFINED_VERTEX_ID;
+   }
+
+   /* Clip coordinates:  interpolate normally
+    */
+   {
+      interp_attr(dst->clip, t, in->clip, out->clip);
+   }
+
+   /* Do the projective divide and insert window coordinates:
+    */
+   {
+      const float *pos = dst->clip;
+      const float *scale = clip->stage.draw->viewport.scale;
+      const float *trans = clip->stage.draw->viewport.translate;
+      const float oow = 1.0f / pos[3];
+
+      dst->data[0][0] = pos[0] * oow * scale[0] + trans[0];
+      dst->data[0][1] = pos[1] * oow * scale[1] + trans[1];
+      dst->data[0][2] = pos[2] * oow * scale[2] + trans[2];
+      dst->data[0][3] = oow;
+   }
+
+   /* Other attributes
+    * Note: start at 1 to skip winpos (data[0]) since we just computed
+    * it above.
+    */
+   for (j = 1; j < nr_attrs; j++) {
+      interp_attr(dst->data[j], t, in->data[j], out->data[j]);
+   }
+}
+
+
+static void emit_poly( struct draw_stage *stage,
+                      struct vertex_header **inlist,
+                      unsigned n,
+                      const struct prim_header *origPrim)
+{
+   struct prim_header header;
+   unsigned i;
+
+   /* later stages may need the determinant, but only the sign matters */
+   header.det = origPrim->det;
+
+   for (i = 2; i < n; i++) {
+      header.v[0] = inlist[i-1];
+      header.v[1] = inlist[i];
+      header.v[2] = inlist[0]; /* keep in v[2] for flatshading */
+       
+      {
+        unsigned tmp1 = header.v[1]->edgeflag;
+        unsigned tmp2 = header.v[2]->edgeflag;
+
+        if (i != n-1) header.v[1]->edgeflag = 0;
+        if (i != 2)   header.v[2]->edgeflag = 0;
+
+         header.edgeflags = ((header.v[0]->edgeflag << 0) | 
+                             (header.v[1]->edgeflag << 1) | 
+                             (header.v[2]->edgeflag << 2));
+
+         if (0) {
+            const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+            uint j, k;
+            debug_printf("Clipped tri:\n");
+            for (j = 0; j < 3; j++) {
+               for (k = 0; k < vs->info.num_outputs; k++) {
+                  debug_printf("  Vert %d: Attr %d:  %f %f %f %f\n", j, k,
+                         header.v[j]->data[k][0],
+                         header.v[j]->data[k][1],
+                         header.v[j]->data[k][2],
+                         header.v[j]->data[k][3]);
+               }
+            }
+         }
+
+        stage->next->tri( stage->next, &header );
+
+        header.v[1]->edgeflag = tmp1;
+        header.v[2]->edgeflag = tmp2;
+      }
+   }
+}
+
+
+
+
+/* Clip a triangle against the viewport and user clip planes.
+ */
+static void
+do_clip_tri( struct draw_stage *stage, 
+            struct prim_header *header,
+            unsigned clipmask )
+{
+   struct clipper *clipper = clipper_stage( stage );
+   struct vertex_header *a[MAX_CLIPPED_VERTICES];
+   struct vertex_header *b[MAX_CLIPPED_VERTICES];
+   struct vertex_header **inlist = a;
+   struct vertex_header **outlist = b;
+   unsigned tmpnr = 0;
+   unsigned n = 3;
+   unsigned i;
+
+   inlist[0] = header->v[0];
+   inlist[1] = header->v[1];
+   inlist[2] = header->v[2];
+
+   while (clipmask && n >= 3) {
+      const unsigned plane_idx = ffs(clipmask)-1;
+      const float *plane = clipper->plane[plane_idx];
+      struct vertex_header *vert_prev = inlist[0];
+      float dp_prev = dot4( vert_prev->clip, plane );
+      unsigned outcount = 0;
+
+      clipmask &= ~(1<<plane_idx);
+
+      inlist[n] = inlist[0]; /* prevent rotation of vertices */
+
+      for (i = 1; i <= n; i++) {
+        struct vertex_header *vert = inlist[i];
+
+        float dp = dot4( vert->clip, plane );
+
+        if (!IS_NEGATIVE(dp_prev)) {
+           outlist[outcount++] = vert_prev;
+        }
+
+        if (DIFFERENT_SIGNS(dp, dp_prev)) {
+           struct vertex_header *new_vert = clipper->stage.tmp[tmpnr++];
+           outlist[outcount++] = new_vert;
+
+           if (IS_NEGATIVE(dp)) {
+              /* Going out of bounds.  Avoid division by zero as we
+               * know dp != dp_prev from DIFFERENT_SIGNS, above.
+               */
+              float t = dp / (dp - dp_prev);
+              interp( clipper, new_vert, t, vert, vert_prev );
+              
+              /* Force edgeflag true in this case:
+               */
+              new_vert->edgeflag = 1;
+           } else {
+              /* Coming back in.
+               */
+              float t = dp_prev / (dp_prev - dp);
+              interp( clipper, new_vert, t, vert_prev, vert );
+
+              /* Copy starting vert's edgeflag:
+               */
+              new_vert->edgeflag = vert_prev->edgeflag;
+           }
+        }
+
+        vert_prev = vert;
+        dp_prev = dp;
+      }
+
+      {
+        struct vertex_header **tmp = inlist;
+        inlist = outlist;
+        outlist = tmp;
+        n = outcount;
+      }
+   }
+
+   /* If flat-shading, copy color to new provoking vertex.
+    */
+   if (clipper->flat && inlist[0] != header->v[2]) {
+      if (1) {
+        inlist[0] = dup_vert(stage, inlist[0], tmpnr++);
+      }
+
+      copy_colors(stage, inlist[0], header->v[2]);
+   }
+
+
+
+   /* Emit the polygon as triangles to the setup stage:
+    */
+   if (n >= 3)
+      emit_poly( stage, inlist, n, header );
+}
+
+
+/* Clip a line against the viewport and user clip planes.
+ */
+static void
+do_clip_line( struct draw_stage *stage,
+             struct prim_header *header,
+             unsigned clipmask )
+{
+   const struct clipper *clipper = clipper_stage( stage );
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   const float *pos0 = v0->clip;
+   const float *pos1 = v1->clip;
+   float t0 = 0.0F;
+   float t1 = 0.0F;
+   struct prim_header newprim;
+
+   while (clipmask) {
+      const unsigned plane_idx = ffs(clipmask)-1;
+      const float *plane = clipper->plane[plane_idx];
+      const float dp0 = dot4( pos0, plane );
+      const float dp1 = dot4( pos1, plane );
+
+      if (dp1 < 0.0F) {
+        float t = dp1 / (dp1 - dp0);
+         t1 = MAX2(t1, t);
+      } 
+
+      if (dp0 < 0.0F) {
+        float t = dp0 / (dp0 - dp1);
+         t0 = MAX2(t0, t);
+      }
+
+      if (t0 + t1 >= 1.0F)
+        return; /* discard */
+
+      clipmask &= ~(1 << plane_idx);  /* turn off this plane's bit */
+   }
+
+   if (v0->clipmask) {
+      interp( clipper, stage->tmp[0], t0, v0, v1 );
+
+      if (clipper->flat)
+        copy_colors(stage, stage->tmp[0], v0);
+
+      newprim.v[0] = stage->tmp[0];
+   }
+   else {
+      newprim.v[0] = v0;
+   }
+
+   if (v1->clipmask) {
+      interp( clipper, stage->tmp[1], t1, v1, v0 );
+      newprim.v[1] = stage->tmp[1];
+   }
+   else {
+      newprim.v[1] = v1;
+   }
+
+   stage->next->line( stage->next, &newprim );
+}
+
+
+static void
+clip_point( struct draw_stage *stage, 
+           struct prim_header *header )
+{
+   if (header->v[0]->clipmask == 0) 
+      stage->next->point( stage->next, header );
+}
+
+
+static void
+clip_line( struct draw_stage *stage,
+          struct prim_header *header )
+{
+   unsigned clipmask = (header->v[0]->clipmask | 
+                        header->v[1]->clipmask);
+   
+   if (clipmask == 0) {
+      /* no clipping needed */
+      stage->next->line( stage->next, header );
+   }
+   else if ((header->v[0]->clipmask &
+             header->v[1]->clipmask) == 0) {
+      do_clip_line(stage, header, clipmask);
+   }
+   /* else, totally clipped */
+}
+
+
+static void
+clip_tri( struct draw_stage *stage,
+         struct prim_header *header )
+{
+   unsigned clipmask = (header->v[0]->clipmask | 
+                        header->v[1]->clipmask | 
+                        header->v[2]->clipmask);
+   
+   if (clipmask == 0) {
+      /* no clipping needed */
+      stage->next->tri( stage->next, header );
+   }
+   else if ((header->v[0]->clipmask & 
+             header->v[1]->clipmask & 
+             header->v[2]->clipmask) == 0) {
+      do_clip_tri(stage, header, clipmask);
+   }
+}
+
+/* Update state.  Could further delay this until we hit the first
+ * primitive that really requires clipping.
+ */
+static void 
+clip_init_state( struct draw_stage *stage )
+{
+   struct clipper *clipper = clipper_stage( stage );
+
+   clipper->flat = stage->draw->rasterizer->flatshade ? TRUE : FALSE;
+
+   if (clipper->flat) {
+      const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+      uint i;
+
+      clipper->num_color_attribs = 0;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+        if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+            vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+           clipper->color_attribs[clipper->num_color_attribs++] = i;
+        }
+      }
+   }
+   
+   stage->tri = clip_tri;
+   stage->line = clip_line;
+}
+
+
+
+static void clip_first_tri( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   clip_init_state( stage );
+   stage->tri( stage, header );
+}
+
+static void clip_first_line( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   clip_init_state( stage );
+   stage->line( stage, header );
+}
+
+
+static void clip_flush( struct draw_stage *stage, 
+                            unsigned flags )
+{
+   stage->tri = clip_first_tri;
+   stage->line = clip_first_line;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void clip_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void clip_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Allocate a new clipper stage.
+ * \return pointer to new stage object
+ */
+struct draw_stage *draw_clip_stage( struct draw_context *draw )
+{
+   struct clipper *clipper = CALLOC_STRUCT(clipper);
+
+   draw_alloc_temp_verts( &clipper->stage, MAX_CLIPPED_VERTICES+1 );
+
+   clipper->stage.draw = draw;
+   clipper->stage.point = clip_point;
+   clipper->stage.line = clip_first_line;
+   clipper->stage.tri = clip_first_tri;
+   clipper->stage.flush = clip_flush;
+   clipper->stage.reset_stipple_counter = clip_reset_stipple_counter;
+   clipper->stage.destroy = clip_destroy;
+
+   clipper->plane = draw->plane;
+
+   return &clipper->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_cull.c b/src/gallium/auxiliary/draw/draw_pipe_cull.c
new file mode 100644 (file)
index 0000000..8177b0a
--- /dev/null
@@ -0,0 +1,150 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Drawing stage for polygon culling
+ */
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+struct cull_stage {
+   struct draw_stage stage;
+   unsigned winding;  /**< which winding(s) to cull (one of PIPE_WINDING_x) */
+};
+
+
+static INLINE struct cull_stage *cull_stage( struct draw_stage *stage )
+{
+   return (struct cull_stage *)stage;
+}
+
+
+
+
+static void cull_tri( struct draw_stage *stage,
+                     struct prim_header *header )
+{
+   /* Window coords: */
+   const float *v0 = header->v[0]->data[0];
+   const float *v1 = header->v[1]->data[0];
+   const float *v2 = header->v[2]->data[0];
+
+   /* edge vectors e = v0 - v2, f = v1 - v2 */
+   const float ex = v0[0] - v2[0];
+   const float ey = v0[1] - v2[1];
+   const float fx = v1[0] - v2[0];
+   const float fy = v1[1] - v2[1];
+   
+   /* det = cross(e,f).z */
+   header->det = ex * fy - ey * fx;
+
+   if (header->det != 0) {
+      /* if (det < 0 then Z points toward camera and triangle is 
+       * counter-clockwise winding.
+       */
+      unsigned winding = (header->det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
+
+      if ((winding & cull_stage(stage)->winding) == 0) {
+         /* triangle is not culled, pass to next stage */
+        stage->next->tri( stage->next, header );
+      }
+   }
+}
+
+static void cull_first_tri( struct draw_stage *stage, 
+                           struct prim_header *header )
+{
+   struct cull_stage *cull = cull_stage(stage);
+
+   cull->winding = stage->draw->rasterizer->cull_mode;
+
+   stage->tri = cull_tri;
+   stage->tri( stage, header );
+}
+
+
+
+static void cull_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void cull_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void cull_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->tri = cull_first_tri;
+   stage->next->flush( stage->next, flags );
+}
+
+static void cull_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void cull_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create a new polygon culling stage.
+ */
+struct draw_stage *draw_cull_stage( struct draw_context *draw )
+{
+   struct cull_stage *cull = CALLOC_STRUCT(cull_stage);
+
+   draw_alloc_temp_verts( &cull->stage, 0 );
+
+   cull->stage.draw = draw;
+   cull->stage.next = NULL;
+   cull->stage.point = cull_point;
+   cull->stage.line = cull_line;
+   cull->stage.tri = cull_first_tri;
+   cull->stage.flush = cull_flush;
+   cull->stage.reset_stipple_counter = cull_reset_stipple_counter;
+   cull->stage.destroy = cull_destroy;
+
+   return &cull->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
new file mode 100644 (file)
index 0000000..54baa1f
--- /dev/null
@@ -0,0 +1,248 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_vs.h"
+
+
+/** subclass of draw_stage */
+struct flat_stage
+{
+   struct draw_stage stage;
+
+   uint num_color_attribs;
+   uint color_attribs[4];  /* front/back primary/secondary colors */
+};
+
+
+static INLINE struct flat_stage *
+flat_stage(struct draw_stage *stage)
+{
+   return (struct flat_stage *) stage;
+}
+
+
+/** Copy all the color attributes from 'src' vertex to 'dst' vertex */
+static INLINE void copy_colors( struct draw_stage *stage,
+                                struct vertex_header *dst,
+                                const struct vertex_header *src )
+{
+   const struct flat_stage *flat = flat_stage(stage);
+   uint i;
+   for (i = 0; i < flat->num_color_attribs; i++) {
+      const uint attr = flat->color_attribs[i];
+      COPY_4FV(dst->data[attr], src->data[attr]);
+   }
+}
+
+
+/** Copy all the color attributes from src vertex to dst0 & dst1 vertices */
+static INLINE void copy_colors2( struct draw_stage *stage,
+                                 struct vertex_header *dst0,
+                                 struct vertex_header *dst1,
+                                 const struct vertex_header *src )
+{
+   const struct flat_stage *flat = flat_stage(stage);
+   uint i;
+   for (i = 0; i < flat->num_color_attribs; i++) {
+      const uint attr = flat->color_attribs[i];
+      COPY_4FV(dst0->data[attr], src->data[attr]);
+      COPY_4FV(dst1->data[attr], src->data[attr]);
+   }
+}
+
+
+/**
+ * Flatshade tri.  Required for clipping and when unfilled tris are
+ * active, otherwise handled by hardware.
+ */
+static void flatshade_tri_0( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.det = header->det;
+   tmp.edgeflags = header->edgeflags;
+   tmp.v[0] = header->v[0];
+   tmp.v[1] = dup_vert(stage, header->v[1], 0);
+   tmp.v[2] = dup_vert(stage, header->v[2], 1);
+
+   copy_colors2(stage, tmp.v[1], tmp.v[2], tmp.v[0]);
+   
+   stage->next->tri( stage->next, &tmp );
+}
+
+
+static void flatshade_tri_2( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.det = header->det;
+   tmp.edgeflags = header->edgeflags;
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = dup_vert(stage, header->v[1], 1);
+   tmp.v[2] = header->v[2];
+
+   copy_colors2(stage, tmp.v[0], tmp.v[1], tmp.v[2]);
+   
+   stage->next->tri( stage->next, &tmp );
+}
+
+
+
+
+
+/**
+ * Flatshade line.  Required for clipping.
+ */
+static void flatshade_line_0( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.v[0] = header->v[0];
+   tmp.v[1] = dup_vert(stage, header->v[1], 0);
+
+   copy_colors(stage, tmp.v[1], tmp.v[0]);
+   
+   stage->next->line( stage->next, &tmp );
+}
+
+static void flatshade_line_1( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = header->v[1];
+
+   copy_colors(stage, tmp.v[0], tmp.v[1]);
+   
+   stage->next->line( stage->next, &tmp );
+}
+
+
+/* Flatshade point -- passthrough.
+ */
+static void flatshade_point( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void flatshade_init_state( struct draw_stage *stage )
+{
+   struct flat_stage *flat = flat_stage(stage);
+   const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+   uint i;
+
+   /* Find which vertex shader outputs are colors, make a list */
+   flat->num_color_attribs = 0;
+   for (i = 0; i < vs->info.num_outputs; i++) {
+      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR ||
+          vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         flat->color_attribs[flat->num_color_attribs++] = i;
+      }
+   }
+
+   /* Choose flatshade routine according to provoking vertex:
+    */
+   if (stage->draw->rasterizer->flatshade_first) {
+      stage->line = flatshade_line_0;
+      stage->tri = flatshade_tri_0;
+   }
+   else {
+      stage->line = flatshade_line_1;
+      stage->tri = flatshade_tri_2;
+   }
+}
+
+static void flatshade_first_tri( struct draw_stage *stage,
+                                struct prim_header *header )
+{
+   flatshade_init_state( stage );
+   stage->tri( stage, header );
+}
+
+static void flatshade_first_line( struct draw_stage *stage,
+                                 struct prim_header *header )
+{
+   flatshade_init_state( stage );
+   stage->line( stage, header );
+}
+
+
+static void flatshade_flush( struct draw_stage *stage, 
+                            unsigned flags )
+{
+   stage->tri = flatshade_first_tri;
+   stage->line = flatshade_first_line;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void flatshade_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void flatshade_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create flatshading drawing stage.
+ */
+struct draw_stage *draw_flatshade_stage( struct draw_context *draw )
+{
+   struct flat_stage *flatshade = CALLOC_STRUCT(flat_stage);
+
+   draw_alloc_temp_verts( &flatshade->stage, 2 );
+
+   flatshade->stage.draw = draw;
+   flatshade->stage.next = NULL;
+   flatshade->stage.point = flatshade_point;
+   flatshade->stage.line = flatshade_first_line;
+   flatshade->stage.tri = flatshade_first_tri;
+   flatshade->stage.flush = flatshade_flush;
+   flatshade->stage.reset_stipple_counter = flatshade_reset_stipple_counter;
+   flatshade->stage.destroy = flatshade_destroy;
+
+   return &flatshade->stage;
+}
+
+
diff --git a/src/gallium/auxiliary/draw/draw_pipe_offset.c b/src/gallium/auxiliary/draw/draw_pipe_offset.c
new file mode 100644 (file)
index 0000000..dbc676d
--- /dev/null
@@ -0,0 +1,186 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  polygon offset state
+ *
+ * \author  Keith Whitwell <keith@tungstengraphics.com>
+ * \author  Brian Paul
+ */
+
+#include "pipe/p_util.h"
+#include "draw_private.h"
+
+
+
+struct offset_stage {
+   struct draw_stage stage;
+
+   float scale;
+   float units;
+};
+
+
+
+static INLINE struct offset_stage *offset_stage( struct draw_stage *stage )
+{
+   return (struct offset_stage *) stage;
+}
+
+
+
+
+
+/**
+ * Offset tri Z.  Some hardware can handle this, but not usually when
+ * doing unfilled rendering.
+ */
+static void do_offset_tri( struct draw_stage *stage,
+                          struct prim_header *header )
+{
+   struct offset_stage *offset = offset_stage(stage);   
+   float inv_det = 1.0f / header->det;
+
+   /* Window coords:
+    */
+   float *v0 = header->v[0]->data[0];
+   float *v1 = header->v[1]->data[0];
+   float *v2 = header->v[2]->data[0];
+
+   /* edge vectors e = v0 - v2, f = v1 - v2 */
+   float ex = v0[0] - v2[0];
+   float ey = v0[1] - v2[1];
+   float ez = v0[2] - v2[2];
+   float fx = v1[0] - v2[0];
+   float fy = v1[1] - v2[1];
+   float fz = v1[2] - v2[2];
+
+   /* (a,b) = cross(e,f).xy */
+   float a = ey*fz - ez*fy;
+   float b = ez*fx - ex*fz;
+
+   float dzdx = FABSF(a * inv_det);
+   float dzdy = FABSF(b * inv_det);
+
+   float zoffset = offset->units + MAX2(dzdx, dzdy) * offset->scale;
+
+   /*
+    * Note: we're applying the offset and clamping per-vertex.
+    * Ideally, the offset is applied per-fragment prior to fragment shading.
+    */
+   v0[2] = CLAMP(v0[2] + zoffset, 0.0f, 1.0f);
+   v1[2] = CLAMP(v1[2] + zoffset, 0.0f, 1.0f);
+   v2[2] = CLAMP(v2[2] + zoffset, 0.0f, 1.0f);
+
+   stage->next->tri( stage->next, header );
+}
+
+
+static void offset_tri( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   struct prim_header tmp;
+
+   tmp.det = header->det;
+   tmp.edgeflags = header->edgeflags;
+   tmp.v[0] = dup_vert(stage, header->v[0], 0);
+   tmp.v[1] = dup_vert(stage, header->v[1], 1);
+   tmp.v[2] = dup_vert(stage, header->v[2], 2);
+
+   do_offset_tri( stage, &tmp );
+}
+
+
+static void offset_first_tri( struct draw_stage *stage, 
+                             struct prim_header *header )
+{
+   struct offset_stage *offset = offset_stage(stage);
+   float mrd = 1.0f / 65535.0f; /* XXX this depends on depthbuffer bits! */
+
+   offset->units = stage->draw->rasterizer->offset_units * mrd;
+   offset->scale = stage->draw->rasterizer->offset_scale;
+
+   stage->tri = offset_tri;
+   stage->tri( stage, header );
+}
+
+
+static void offset_line( struct draw_stage *stage,
+                        struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void offset_point( struct draw_stage *stage,
+                         struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void offset_flush( struct draw_stage *stage,
+                         unsigned flags )
+{
+   stage->tri = offset_first_tri;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void offset_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void offset_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create polygon offset drawing stage.
+ */
+struct draw_stage *draw_offset_stage( struct draw_context *draw )
+{
+   struct offset_stage *offset = CALLOC_STRUCT(offset_stage);
+
+   draw_alloc_temp_verts( &offset->stage, 3 );
+
+   offset->stage.draw = draw;
+   offset->stage.next = NULL;
+   offset->stage.point = offset_point;
+   offset->stage.line = offset_line;
+   offset->stage.tri = offset_first_tri;
+   offset->stage.flush = offset_flush;
+   offset->stage.reset_stipple_counter = offset_reset_stipple_counter;
+   offset->stage.destroy = offset_destroy;
+
+   return &offset->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
new file mode 100644 (file)
index 0000000..4dddb72
--- /dev/null
@@ -0,0 +1,746 @@
+/**************************************************************************
+ * 
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * Polygon stipple stage:  implement polygon stipple with texture map and
+ * fragment program.  The fragment program samples the texture and does
+ * a fragment kill for the stipple-failing fragments.
+ *
+ * Authors:  Brian Paul
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_context.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "tgsi/util/tgsi_transform.h"
+#include "tgsi/util/tgsi_dump.h"
+
+#include "draw_context.h"
+#include "draw_private.h"
+
+
+
+/**
+ * Subclass of pipe_shader_state to carry extra fragment shader info.
+ */
+struct pstip_fragment_shader
+{
+   struct pipe_shader_state state;
+   void *driver_fs;
+   void *pstip_fs;
+   uint sampler_unit;
+};
+
+
+/**
+ * Subclass of draw_stage
+ */
+struct pstip_stage
+{
+   struct draw_stage stage;
+
+   void *sampler_cso;
+   struct pipe_texture *texture;
+   uint num_samplers;
+   uint num_textures;
+
+   /*
+    * Currently bound state
+    */
+   struct pstip_fragment_shader *fs;
+   struct {
+      void *samplers[PIPE_MAX_SAMPLERS];
+      struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
+      const struct pipe_poly_stipple *stipple;
+   } state;
+
+   /*
+    * Driver interface/override functions
+    */
+   void * (*driver_create_fs_state)(struct pipe_context *,
+                                    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 *, unsigned, void **);
+
+   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
+                                       struct pipe_texture **);
+
+   void (*driver_set_polygon_stipple)(struct pipe_context *,
+                                      const struct pipe_poly_stipple *);
+
+   struct pipe_context *pipe;
+};
+
+
+
+/**
+ * Subclass of tgsi_transform_context, used for transforming the
+ * user's fragment shader to add the special AA instructions.
+ */
+struct pstip_transform_context {
+   struct tgsi_transform_context base;
+   uint tempsUsed;  /**< bitmask */
+   int wincoordInput;
+   int maxInput;
+   uint samplersUsed;  /**< bitfield of samplers used */
+   int freeSampler;  /** an available sampler for the pstipple */
+   int texTemp;  /**< temp registers */
+   int numImmed;
+   boolean firstInstruction;
+};
+
+
+/**
+ * TGSI declaration transform callback.
+ * Look for a free sampler, a free input attrib, and two free temp regs.
+ */
+static void
+pstip_transform_decl(struct tgsi_transform_context *ctx,
+                     struct tgsi_full_declaration *decl)
+{
+   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
+
+   if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         pctx->samplersUsed |= 1 << i;
+      }
+   }
+   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
+      pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
+      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION)
+         pctx->wincoordInput = (int) decl->u.DeclarationRange.First;
+   }
+   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
+      uint i;
+      for (i = decl->u.DeclarationRange.First;
+           i <= decl->u.DeclarationRange.Last; i++) {
+         pctx->tempsUsed |= (1 << i);
+      }
+   }
+
+   ctx->emit_declaration(ctx, decl);
+}
+
+
+static void
+pstip_transform_immed(struct tgsi_transform_context *ctx,
+                      struct tgsi_full_immediate *immed)
+{
+   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
+   pctx->numImmed++;
+}
+
+
+/**
+ * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
+ */
+static int
+free_bit(uint bitfield)
+{
+   int i;
+   for (i = 0; i < 32; i++) {
+      if ((bitfield & (1 << i)) == 0)
+         return i;
+   }
+   return -1;
+}
+
+
+/**
+ * TGSI instruction transform callback.
+ * Replace writes to result.color w/ a temp reg.
+ * Upon END instruction, insert texture sampling code for antialiasing.
+ */
+static void
+pstip_transform_inst(struct tgsi_transform_context *ctx,
+                     struct tgsi_full_instruction *inst)
+{
+   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
+
+   if (pctx->firstInstruction) {
+      /* emit our new declarations before the first instruction */
+
+      struct tgsi_full_declaration decl;
+      struct tgsi_full_instruction newInst;
+      uint i;
+      int wincoordInput;
+
+      /* find free sampler */
+      pctx->freeSampler = free_bit(pctx->samplersUsed);
+      if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
+         pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
+
+      if (pctx->wincoordInput < 0)
+         wincoordInput = pctx->maxInput + 1;
+      else
+         wincoordInput = pctx->wincoordInput;
+
+      /* find one free temp reg */
+      for (i = 0; i < 32; i++) {
+         if ((pctx->tempsUsed & (1 << i)) == 0) {
+            /* found a free temp */
+            if (pctx->texTemp < 0)
+               pctx->texTemp  = i;
+            else
+               break;
+         }
+      }
+      assert(pctx->texTemp >= 0);
+
+      if (pctx->wincoordInput < 0) {
+         /* declare new position input reg */
+         decl = tgsi_default_full_declaration();
+         decl.Declaration.File = TGSI_FILE_INPUT;
+         decl.Declaration.Semantic = 1;
+         decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
+         decl.Semantic.SemanticIndex = 0;
+         decl.Declaration.Interpolate = 1;
+         decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
+         decl.u.DeclarationRange.First = 
+            decl.u.DeclarationRange.Last = wincoordInput;
+         ctx->emit_declaration(ctx, &decl);
+      }
+
+      /* declare new sampler */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_SAMPLER;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = pctx->freeSampler;
+      ctx->emit_declaration(ctx, &decl);
+
+      /* declare new temp regs */
+      decl = tgsi_default_full_declaration();
+      decl.Declaration.File = TGSI_FILE_TEMPORARY;
+      decl.u.DeclarationRange.First = 
+      decl.u.DeclarationRange.Last = pctx->texTemp;
+      ctx->emit_declaration(ctx, &decl);
+
+      /* emit immediate = {1/32, 1/32, 1, 1}
+       * The index/position of this immediate will be pctx->numImmed
+       */
+      {
+         static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
+         struct tgsi_full_immediate immed;
+         uint size = 4;
+         immed = tgsi_default_full_immediate();
+         immed.Immediate.Size = 1 + size; /* one for the token itself */
+         immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value;
+         ctx->emit_immediate(ctx, &immed);
+      }
+
+      pctx->firstInstruction = FALSE;
+
+
+      /* 
+       * Insert new MUL/TEX/KILP instructions at start of program
+       * Take gl_FragCoord, divide by 32 (stipple size), sample the
+       * texture and kill fragment if needed.
+       *
+       * We'd like to use non-normalized texcoords to index into a RECT
+       * texture, but we can only use GL_REPEAT wrap mode with normalized
+       * texcoords.  Darn.
+       */
+
+      /* MUL texTemp, INPUT[wincoord], 1/32; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* TEX texTemp, texTemp, sampler; */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
+      newInst.Instruction.NumDstRegs = 1;
+      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
+      newInst.Instruction.NumSrcRegs = 2;
+      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
+      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
+      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler;
+      ctx->emit_instruction(ctx, &newInst);
+
+      /* KILP texTemp;   # if texTemp < 0, KILL fragment */
+      newInst = tgsi_default_full_instruction();
+      newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
+      newInst.Instruction.NumDstRegs = 0;
+      newInst.Instruction.NumSrcRegs = 1;
+      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
+      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
+      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
+      ctx->emit_instruction(ctx, &newInst);
+   }
+
+   /* emit this instruction */
+   ctx->emit_instruction(ctx, inst);
+}
+
+
+/**
+ * Generate the frag shader we'll use for doing polygon stipple.
+ * This will be the user's shader prefixed with a TEX and KIL instruction.
+ */
+static void
+generate_pstip_fs(struct pstip_stage *pstip)
+{
+   const struct pipe_shader_state *orig_fs = &pstip->fs->state;
+   /*struct draw_context *draw = pstip->stage.draw;*/
+   struct pipe_shader_state pstip_fs;
+   struct pstip_transform_context transform;
+
+#define MAX 1000
+
+   pstip_fs = *orig_fs; /* copy to init */
+   pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
+
+   memset(&transform, 0, sizeof(transform));
+   transform.wincoordInput = -1;
+   transform.maxInput = -1;
+   transform.texTemp = -1;
+   transform.firstInstruction = TRUE;
+   transform.base.transform_instruction = pstip_transform_inst;
+   transform.base.transform_declaration = pstip_transform_decl;
+   transform.base.transform_immediate = pstip_transform_immed;
+
+   tgsi_transform_shader(orig_fs->tokens,
+                         (struct tgsi_token *) pstip_fs.tokens,
+                         MAX, &transform.base);
+
+#if 0 /* DEBUG */
+   tgsi_dump(orig_fs->tokens, 0);
+   tgsi_dump(pstip_fs.tokens, 0);
+#endif
+
+   pstip->fs->sampler_unit = transform.freeSampler;
+   assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
+
+   pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
+}
+
+
+/**
+ * Load texture image with current stipple pattern.
+ */
+static void
+pstip_update_texture(struct pstip_stage *pstip)
+{
+   static const uint bit31 = 1 << 31;
+   struct pipe_context *pipe = pstip->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_surface *surface;
+   const uint *stipple = pstip->state.stipple->stipple;
+   uint i, j;
+   ubyte *data;
+
+   surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0);
+   data = pipe_surface_map(surface);
+
+   /*
+    * Load alpha texture.
+    * Note: 0 means keep the fragment, 255 means kill it.
+    * We'll negate the texel value and use KILP which kills if value
+    * is negative.
+    */
+   for (i = 0; i < 32; i++) {
+      for (j = 0; j < 32; j++) {
+         if (stipple[i] & (bit31 >> j)) {
+            /* fragment "on" */
+            data[i * surface->pitch + j] = 0;
+         }
+         else {
+            /* fragment "off" */
+            data[i * surface->pitch + j] = 255;
+         }
+      }
+   }
+
+   /* unmap */
+   pipe_surface_unmap(surface);
+   pipe_surface_reference(&surface, NULL);
+   pipe->texture_update(pipe, pstip->texture, 0, 0x1);
+}
+
+
+/**
+ * Create the texture map we'll use for stippling.
+ */
+static void
+pstip_create_texture(struct pstip_stage *pstip)
+{
+   struct pipe_context *pipe = pstip->pipe;
+   struct pipe_screen *screen = pipe->screen;
+   struct pipe_texture texTemp;
+
+   memset(&texTemp, 0, sizeof(texTemp));
+   texTemp.target = PIPE_TEXTURE_2D;
+   texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */
+   texTemp.last_level = 0;
+   texTemp.width[0] = 32;
+   texTemp.height[0] = 32;
+   texTemp.depth[0] = 1;
+   texTemp.cpp = 1;
+
+   pstip->texture = screen->texture_create(screen, &texTemp);
+   assert(pstip->texture->refcount == 1);
+}
+
+
+/**
+ * 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 void
+pstip_create_sampler(struct pstip_stage *pstip)
+{
+   struct pipe_sampler_state sampler;
+   struct pipe_context *pipe = pstip->pipe;
+
+   memset(&sampler, 0, sizeof(sampler));
+   sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
+   sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
+   sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
+   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+   sampler.normalized_coords = 1;
+   sampler.min_lod = 0.0f;
+   sampler.max_lod = 0.0f;
+
+   pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
+}
+
+
+/**
+ * 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.
+ */
+static void
+bind_pstip_fragment_shader(struct pstip_stage *pstip)
+{
+   if (!pstip->fs->pstip_fs) {
+      generate_pstip_fs(pstip);
+   }
+   pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs);
+}
+
+
+
+static INLINE struct pstip_stage *
+pstip_stage( struct draw_stage *stage )
+{
+   return (struct pstip_stage *) stage;
+}
+
+
+static void
+passthrough_point(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->point(stage->next, header);
+}
+
+
+static void
+passthrough_line(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->line(stage->next, header);
+}
+
+
+static void
+passthrough_tri(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+
+static void
+pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
+{
+   struct pstip_stage *pstip = pstip_stage(stage);
+   struct pipe_context *pipe = pstip->pipe;
+   uint num_samplers;
+
+   assert(stage->draw->rasterizer->poly_stipple_enable);
+
+   /* bind our fragprog */
+   bind_pstip_fragment_shader(pstip);
+
+   /* how many samplers? */
+   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
+   num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
+   num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);
+
+   /* plug in our sampler, texture */
+   pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso;
+   pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit],
+                          pstip->texture);
+
+   assert(num_samplers <= PIPE_MAX_SAMPLERS);
+
+   pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
+   pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
+
+   /* now really draw first line */
+   stage->tri = passthrough_tri;
+   stage->tri(stage, header);
+}
+
+
+static void
+pstip_flush(struct draw_stage *stage, unsigned flags)
+{
+   /*struct draw_context *draw = stage->draw;*/
+   struct pstip_stage *pstip = pstip_stage(stage);
+   struct pipe_context *pipe = pstip->pipe;
+
+   stage->tri = pstip_first_tri;
+   stage->next->flush( stage->next, flags );
+
+   /* restore original frag shader */
+   pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
+
+   /* XXX restore original texture, sampler state */
+   pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
+                                     pstip->state.samplers);
+   pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
+                                      pstip->state.textures);
+}
+
+
+static void
+pstip_reset_stipple_counter(struct draw_stage *stage)
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void
+pstip_destroy(struct draw_stage *stage)
+{
+   struct pstip_stage *pstip = pstip_stage(stage);
+
+   pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);
+
+   pipe_texture_release(&pstip->texture);
+
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+static struct pstip_stage *
+draw_pstip_stage(struct draw_context *draw)
+{
+   struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage);
+
+   draw_alloc_temp_verts( &pstip->stage, 8 );
+
+   pstip->stage.draw = draw;
+   pstip->stage.next = NULL;
+   pstip->stage.point = passthrough_point;
+   pstip->stage.line = passthrough_line;
+   pstip->stage.tri = pstip_first_tri;
+   pstip->stage.flush = pstip_flush;
+   pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter;
+   pstip->stage.destroy = pstip_destroy;
+
+   return pstip;
+}
+
+
+static struct pstip_stage *
+pstip_stage_from_pipe(struct pipe_context *pipe)
+{
+   struct draw_context *draw = (struct draw_context *) pipe->draw;
+   return pstip_stage(draw->pipeline.pstipple);
+}
+
+
+/**
+ * This function overrides the driver's create_fs_state() function and
+ * will typically be called by the state tracker.
+ */
+static void *
+pstip_create_fs_state(struct pipe_context *pipe,
+                       const struct pipe_shader_state *fs)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader);
+
+   if (aafs) {
+      aafs->state = *fs;
+
+      /* pass-through */
+      aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs);
+   }
+
+   return aafs;
+}
+
+
+static void
+pstip_bind_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
+   /* save current */
+   pstip->fs = aafs;
+   /* pass-through */
+   pstip->driver_bind_fs_state(pstip->pipe,
+                               (aafs ? aafs->driver_fs : NULL));
+}
+
+
+static void
+pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
+   /* pass-through */
+   pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs);
+   FREE(aafs);
+}
+
+
+static void
+pstip_bind_sampler_states(struct pipe_context *pipe,
+                          unsigned num, void **sampler)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   uint i;
+
+   /* save current */
+   memcpy(pstip->state.samplers, sampler, num * sizeof(void *));
+   for (i = num; i < PIPE_MAX_SAMPLERS; i++) {
+      pstip->state.samplers[i] = NULL;
+   }
+
+   pstip->num_samplers = num;
+   /* pass-through */
+   pstip->driver_bind_sampler_states(pstip->pipe, num, sampler);
+}
+
+
+static void
+pstip_set_sampler_textures(struct pipe_context *pipe,
+                           unsigned num, struct pipe_texture **texture)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   uint i;
+
+   /* save current */
+   for (i = 0; i < num; i++) {
+      pipe_texture_reference(&pstip->state.textures[i], texture[i]);
+   }
+   for (; i < PIPE_MAX_SAMPLERS; i++) {
+      pipe_texture_reference(&pstip->state.textures[i], NULL);
+   }
+
+   pstip->num_textures = num;
+
+   /* pass-through */
+   pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
+}
+
+
+static void
+pstip_set_polygon_stipple(struct pipe_context *pipe,
+                          const struct pipe_poly_stipple *stipple)
+{
+   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
+   /* save current */
+   pstip->state.stipple = stipple;
+   /* pass-through */
+   pstip->driver_set_polygon_stipple(pstip->pipe, stipple);
+
+   pstip_update_texture(pstip);
+}
+
+
+
+/**
+ * Called by drivers that want to install this AA line prim stage
+ * into the draw module's pipeline.  This will not be used if the
+ * hardware has native support for AA lines.
+ */
+void
+draw_install_pstipple_stage(struct draw_context *draw,
+                            struct pipe_context *pipe)
+{
+   struct pstip_stage *pstip;
+
+   pipe->draw = (void *) draw;
+
+   /*
+    * Create / install AA line drawing / prim stage
+    */
+   pstip = draw_pstip_stage( draw );
+   assert(pstip);
+   draw->pipeline.pstipple = &pstip->stage;
+
+   pstip->pipe = pipe;
+
+   /* create special texture, sampler state */
+   pstip_create_texture(pstip);
+   pstip_create_sampler(pstip);
+
+   /* save original driver functions */
+   pstip->driver_create_fs_state = pipe->create_fs_state;
+   pstip->driver_bind_fs_state = pipe->bind_fs_state;
+   pstip->driver_delete_fs_state = pipe->delete_fs_state;
+
+   pstip->driver_bind_sampler_states = pipe->bind_sampler_states;
+   pstip->driver_set_sampler_textures = pipe->set_sampler_textures;
+   pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
+
+   /* override the driver's functions */
+   pipe->create_fs_state = pstip_create_fs_state;
+   pipe->bind_fs_state = pstip_bind_fs_state;
+   pipe->delete_fs_state = pstip_delete_fs_state;
+
+   pipe->bind_sampler_states = pstip_bind_sampler_states;
+   pipe->set_sampler_textures = pstip_set_sampler_textures;
+   pipe->set_polygon_stipple = pstip_set_polygon_stipple;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_stipple.c b/src/gallium/auxiliary/draw/draw_pipe_stipple.c
new file mode 100644 (file)
index 0000000..506f335
--- /dev/null
@@ -0,0 +1,239 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+/* Implement line stipple by cutting lines up into smaller lines.
+ * There are hundreds of ways to implement line stipple, this is one
+ * choice that should work in all situations, requires no state
+ * manipulations, but with a penalty in terms of large amounts of
+ * generated geometry.
+ */
+
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_private.h"
+
+
+/** Subclass of draw_stage */
+struct stipple_stage {
+   struct draw_stage stage;
+   float counter;
+   uint pattern;
+   uint factor;
+};
+
+
+static INLINE struct stipple_stage *
+stipple_stage(struct draw_stage *stage)
+{
+   return (struct stipple_stage *) stage;
+}
+
+
+/**
+ * Compute interpolated vertex attributes for 'dst' at position 't' 
+ * between 'v0' and 'v1'.
+ * XXX using linear interpolation for all attribs at this time.
+ */
+static void
+screen_interp( struct draw_context *draw,
+               struct vertex_header *dst,
+               float t,
+               const struct vertex_header *v0, 
+               const struct vertex_header *v1 )
+{
+   uint attr;
+   for (attr = 0; attr < draw->num_vs_outputs; attr++) {
+      const float *val0 = v0->data[attr];
+      const float *val1 = v1->data[attr];
+      float *newv = dst->data[attr];
+      uint i;
+      for (i = 0; i < 4; i++) {
+         newv[i] = val0[i] + t * (val1[i] - val0[i]);
+      }
+   }
+}
+
+
+static void
+emit_segment(struct draw_stage *stage, struct prim_header *header,
+             float t0, float t1)
+{
+   struct vertex_header *v0new = dup_vert(stage, header->v[0], 0);
+   struct vertex_header *v1new = dup_vert(stage, header->v[1], 1);
+   struct prim_header newprim = *header;
+
+   if (t0 > 0.0) {
+      screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] );
+      newprim.v[0] = v0new;
+   }
+
+   if (t1 < 1.0) {
+      screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] );
+      newprim.v[1] = v1new;
+   }
+
+   stage->next->line( stage->next, &newprim );
+}
+
+
+static INLINE unsigned
+stipple_test(int counter, ushort pattern, int factor)
+{
+   int b = (counter / factor) & 0xf;
+   return (1 << b) & pattern;
+}
+
+
+static void
+stipple_line(struct draw_stage *stage, struct prim_header *header)
+{
+   struct stipple_stage *stipple = stipple_stage(stage);
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   const float *pos0 = v0->data[0];
+   const float *pos1 = v1->data[0];
+   float start = 0;
+   int state = 0;
+
+   float x0 = pos0[0];
+   float x1 = pos1[0];
+   float y0 = pos0[1];
+   float y1 = pos1[1];
+
+   float dx = x0 > x1 ? x0 - x1 : x1 - x0;
+   float dy = y0 > y1 ? y0 - y1 : y1 - y0;
+
+   float length = MAX2(dx, dy);
+   int i;
+
+   /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table.
+    */
+   for (i = 0; i < length; i++) {
+      int result = stipple_test( (int) stipple->counter+i,
+                                 (ushort) stipple->pattern, stipple->factor );
+      if (result != state) {
+         /* changing from "off" to "on" or vice versa */
+        if (state) {
+           if (start != i) {
+               /* finishing an "on" segment */
+              emit_segment( stage, header, start / length, i / length );
+            }
+        }
+        else {
+            /* starting an "on" segment */
+           start = (float) i;
+        }
+        state = result;           
+      }
+   }
+
+   if (state && start < length)
+      emit_segment( stage, header, start / length, 1.0 );
+
+   stipple->counter += length;
+}
+
+
+static void
+reset_stipple_counter(struct draw_stage *stage)
+{
+   struct stipple_stage *stipple = stipple_stage(stage);
+   stipple->counter = 0;
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void
+stipple_first_line(struct draw_stage *stage, 
+                  struct prim_header *header)
+{
+   struct stipple_stage *stipple = stipple_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   stipple->pattern = draw->rasterizer->line_stipple_pattern;
+   stipple->factor = draw->rasterizer->line_stipple_factor + 1;
+
+   stage->line = stipple_line;
+   stage->line( stage, header );
+}
+
+
+static void
+stipple_flush(struct draw_stage *stage, unsigned flags)
+{
+   stage->line = stipple_first_line;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void
+passthrough_point(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void
+passthrough_tri(struct draw_stage *stage, struct prim_header *header)
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+static void 
+stipple_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create line stippler stage
+ */
+struct draw_stage *draw_stipple_stage( struct draw_context *draw )
+{
+   struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage);
+
+   draw_alloc_temp_verts( &stipple->stage, 2 );
+
+   stipple->stage.draw = draw;
+   stipple->stage.next = NULL;
+   stipple->stage.point = passthrough_point;
+   stipple->stage.line = stipple_first_line;
+   stipple->stage.tri = passthrough_tri;
+   stipple->stage.reset_stipple_counter = reset_stipple_counter;
+   stipple->stage.flush = stipple_flush;
+   stipple->stage.destroy = stipple_destroy;
+
+   return &stipple->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
new file mode 100644 (file)
index 0000000..01d905c
--- /dev/null
@@ -0,0 +1,203 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_vs.h"
+
+
+struct twoside_stage {
+   struct draw_stage stage;
+   float sign;         /**< +1 or -1 */
+   uint attrib_front0, attrib_back0;
+   uint attrib_front1, attrib_back1;
+};
+
+
+static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage )
+{
+   return (struct twoside_stage *)stage;
+}
+
+
+
+
+/**
+ * Copy back color(s) to front color(s).
+ */
+static INLINE struct vertex_header *
+copy_bfc( struct twoside_stage *twoside, 
+          const struct vertex_header *v,
+          unsigned idx )
+{   
+   struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
+   
+   if (twoside->attrib_back0) {
+      COPY_4FV(tmp->data[twoside->attrib_front0],
+               tmp->data[twoside->attrib_back0]);
+   }
+   if (twoside->attrib_back1) {
+      COPY_4FV(tmp->data[twoside->attrib_front1],
+               tmp->data[twoside->attrib_back1]);
+   }
+
+   return tmp;
+}
+
+
+/* Twoside tri:
+ */
+static void twoside_tri( struct draw_stage *stage,
+                        struct prim_header *header )
+{
+   struct twoside_stage *twoside = twoside_stage(stage);
+
+   if (header->det * twoside->sign < 0.0) {
+      /* this is a back-facing triangle */
+      struct prim_header tmp;
+
+      tmp.det = header->det;
+      tmp.edgeflags = header->edgeflags;
+      /* copy back attribs to front attribs */
+      tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
+      tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
+      tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
+
+      stage->next->tri( stage->next, &tmp );
+   }
+   else {
+      stage->next->tri( stage->next, header );
+   }
+}
+
+
+static void twoside_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   /* pass-through */
+   stage->next->line( stage->next, header );
+}
+
+
+static void twoside_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   /* pass-through */
+   stage->next->point( stage->next, header );
+}
+
+
+static void twoside_first_tri( struct draw_stage *stage, 
+                              struct prim_header *header )
+{
+   struct twoside_stage *twoside = twoside_stage(stage);
+   const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
+   uint i;
+
+   twoside->attrib_front0 = 0;
+   twoside->attrib_front1 = 0;
+   twoside->attrib_back0 = 0;
+   twoside->attrib_back1 = 0;
+
+   /* Find which vertex shader outputs are front/back colors */
+   for (i = 0; i < vs->info.num_outputs; i++) {
+      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
+         if (vs->info.output_semantic_index[i] == 0)
+            twoside->attrib_front0 = i;
+         else
+            twoside->attrib_front1 = i;
+      }
+      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
+         if (vs->info.output_semantic_index[i] == 0)
+            twoside->attrib_back0 = i;
+         else
+            twoside->attrib_back1 = i;
+      }
+   }
+
+   if (!twoside->attrib_back0)
+      twoside->attrib_front0 = 0;
+
+   if (!twoside->attrib_back1)
+      twoside->attrib_front1 = 0;
+
+   /*
+    * We'll multiply the primitive's determinant by this sign to determine
+    * if the triangle is back-facing (negative).
+    * sign = -1 for CCW, +1 for CW
+    */
+   twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
+
+   stage->tri = twoside_tri;
+   stage->tri( stage, header );
+}
+
+
+static void twoside_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->tri = twoside_first_tri;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void twoside_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void twoside_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create twoside pipeline stage.
+ */
+struct draw_stage *draw_twoside_stage( struct draw_context *draw )
+{
+   struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
+
+   draw_alloc_temp_verts( &twoside->stage, 3 );
+
+   twoside->stage.draw = draw;
+   twoside->stage.next = NULL;
+   twoside->stage.point = twoside_point;
+   twoside->stage.line = twoside_line;
+   twoside->stage.tri = twoside_first_tri;
+   twoside->stage.flush = twoside_flush;
+   twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
+   twoside->stage.destroy = twoside_destroy;
+
+   return &twoside->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_unfilled.c b/src/gallium/auxiliary/draw/draw_pipe_unfilled.c
new file mode 100644 (file)
index 0000000..b07860c
--- /dev/null
@@ -0,0 +1,206 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/**
+ * \brief  Drawing stage for handling glPolygonMode(line/point).
+ * Convert triangles to points or lines as needed.
+ */
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+
+struct unfilled_stage {
+   struct draw_stage stage;
+
+   /** [0] = front face, [1] = back face.
+    * legal values:  PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE,
+    * and PIPE_POLYGON_MODE_POINT,
+    */
+   unsigned mode[2];
+};
+
+
+static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage )
+{
+   return (struct unfilled_stage *)stage;
+}
+
+
+
+static void point( struct draw_stage *stage,
+                  struct vertex_header *v0 )
+{
+   struct prim_header tmp;
+   tmp.v[0] = v0;
+   stage->next->point( stage->next, &tmp );
+}
+
+static void line( struct draw_stage *stage,
+                 struct vertex_header *v0,
+                 struct vertex_header *v1 )
+{
+   struct prim_header tmp;
+   tmp.v[0] = v0;
+   tmp.v[1] = v1;
+   stage->next->line( stage->next, &tmp );
+}
+
+
+static void points( struct draw_stage *stage,
+                   struct prim_header *header )
+{
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   struct vertex_header *v2 = header->v[2];
+
+   if (header->edgeflags & 0x1) point( stage, v0 );
+   if (header->edgeflags & 0x2) point( stage, v1 );
+   if (header->edgeflags & 0x4) point( stage, v2 );
+}
+
+
+static void lines( struct draw_stage *stage,
+                  struct prim_header *header )
+{
+   struct vertex_header *v0 = header->v[0];
+   struct vertex_header *v1 = header->v[1];
+   struct vertex_header *v2 = header->v[2];
+
+#if 0
+   assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag);
+   assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag);
+   assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag);
+#endif
+
+   if (header->edgeflags & 0x4) line( stage, v2, v0 );
+   if (header->edgeflags & 0x1) line( stage, v0, v1 );
+   if (header->edgeflags & 0x2) line( stage, v1, v2 );
+}
+
+
+/* Unfilled tri:  
+ *
+ * Note edgeflags in the vertex struct is not sufficient as we will
+ * need to manipulate them when decomposing primitives???
+ */
+static void unfilled_tri( struct draw_stage *stage,
+                         struct prim_header *header )
+{
+   struct unfilled_stage *unfilled = unfilled_stage(stage);
+   unsigned mode = unfilled->mode[header->det >= 0.0];
+  
+   switch (mode) {
+   case PIPE_POLYGON_MODE_FILL:
+      stage->next->tri( stage->next, header );
+      break;
+   case PIPE_POLYGON_MODE_LINE:
+      lines( stage, header );
+      break;
+   case PIPE_POLYGON_MODE_POINT:
+      points( stage, header );
+      break;
+   default:
+      assert(0);
+   }   
+}
+
+
+static void unfilled_first_tri( struct draw_stage *stage, 
+                               struct prim_header *header )
+{
+   struct unfilled_stage *unfilled = unfilled_stage(stage);
+
+   unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
+   unfilled->mode[1] = stage->draw->rasterizer->fill_cw;  /* back */
+
+   stage->tri = unfilled_tri;
+   stage->tri( stage, header );
+}
+
+
+static void unfilled_line( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   stage->next->line( stage->next, header );
+}
+
+
+static void unfilled_point( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void unfilled_flush( struct draw_stage *stage,
+                           unsigned flags )
+{
+   stage->next->flush( stage->next, flags );
+
+   stage->tri = unfilled_first_tri;
+}
+
+
+static void unfilled_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void unfilled_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+/**
+ * Create unfilled triangle stage.
+ */
+struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
+{
+   struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
+
+   draw_alloc_temp_verts( &unfilled->stage, 0 );
+
+   unfilled->stage.draw = draw;
+   unfilled->stage.next = NULL;
+   unfilled->stage.tmp = NULL;
+   unfilled->stage.point = unfilled_point;
+   unfilled->stage.line = unfilled_line;
+   unfilled->stage.tri = unfilled_first_tri;
+   unfilled->stage.flush = unfilled_flush;
+   unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
+   unfilled->stage.destroy = unfilled_destroy;
+
+   return &unfilled->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_validate.c b/src/gallium/auxiliary/draw/draw_pipe_validate.c
new file mode 100644 (file)
index 0000000..e163e07
--- /dev/null
@@ -0,0 +1,312 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "draw_private.h"
+
+static boolean points( unsigned prim )
+{
+   return (prim == PIPE_PRIM_POINTS);
+}
+
+static boolean lines( unsigned prim )
+{
+   return (prim == PIPE_PRIM_LINES ||
+           prim == PIPE_PRIM_LINE_STRIP ||
+           prim == PIPE_PRIM_LINE_LOOP);
+}
+
+static boolean triangles( unsigned prim )
+{
+   return prim >= PIPE_PRIM_TRIANGLES;
+}
+
+/**
+ * Check if we need any special pipeline stages, or whether
+ * prims/verts can go through untouched.  Don't test for bypass
+ * clipping or vs modes, this function is just about the primitive
+ * pipeline stages.
+ */
+boolean
+draw_need_pipeline(const struct draw_context *draw, 
+                   unsigned int prim )
+{
+   /* Don't have to worry about triangles turning into lines/points
+    * and triggering the pipeline, because we have to trigger the
+    * pipeline *anyway* if unfilled mode is active.
+    */
+   if (lines(prim)) 
+   {
+      /* line stipple */
+      if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
+         return TRUE;
+
+      /* wide lines */
+      if (draw->rasterizer->line_width > draw->wide_line_threshold)
+         return TRUE;
+
+      /* AA lines */
+      if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
+         return TRUE;
+   }
+
+   if (points(prim))
+   {
+      /* large points */
+      if (draw->rasterizer->point_size > draw->wide_point_threshold)
+         return TRUE;
+
+      /* AA points */
+      if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
+         return TRUE;
+
+      /* point sprites */
+      if (draw->rasterizer->point_sprite && draw->point_sprite)
+         return TRUE;
+   }
+
+
+   if (triangles(prim)) 
+   {
+      /* polygon stipple */
+      if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
+         return TRUE;
+
+      /* unfilled polygons */
+      if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+          draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
+         return TRUE;
+      
+      /* polygon offset */
+      if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
+         return TRUE;
+
+      /* two-side lighting */
+      if (draw->rasterizer->light_twoside)
+         return TRUE;
+   }
+
+   /* polygon cull - this is difficult - hardware can cull just fine
+    * most of the time (though sometimes CULL_NEITHER is unsupported.
+    * 
+    * Generally this isn't a reason to require the pipeline, though.
+    *
+   if (draw->rasterizer->cull_mode)
+      return TRUE;
+    */
+
+   return FALSE;
+}
+
+
+
+/**
+ * Rebuild the rendering pipeline.
+ */
+static struct draw_stage *validate_pipeline( struct draw_stage *stage )
+{
+   struct draw_context *draw = stage->draw;
+   struct draw_stage *next = draw->pipeline.rasterize;
+   int need_det = 0;
+   int precalc_flat = 0;
+   boolean wide_lines, wide_points;
+
+   /* Set the validate's next stage to the rasterize stage, so that it
+    * can be found later if needed for flushing.
+    */
+   stage->next = next;
+
+   /* drawing wide lines? */
+   wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold
+                 && !draw->rasterizer->line_smooth);
+
+   /* drawing large points? */
+   if (draw->rasterizer->point_sprite && draw->point_sprite)
+      wide_points = TRUE;
+   else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
+      wide_points = FALSE;
+   else if (draw->rasterizer->point_size > draw->wide_point_threshold)
+      wide_points = TRUE;
+   else
+      wide_points = FALSE;
+
+   /*
+    * NOTE: we build up the pipeline in end-to-start order.
+    *
+    * TODO: make the current primitive part of the state and build
+    * shorter pipelines for lines & points.
+    */
+
+   if (draw->rasterizer->line_smooth && draw->pipeline.aaline) {
+      draw->pipeline.aaline->next = next;
+      next = draw->pipeline.aaline;
+   }
+
+   if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) {
+      draw->pipeline.aapoint->next = next;
+      next = draw->pipeline.aapoint;
+   }
+
+   if (wide_lines) {
+      draw->pipeline.wide_line->next = next;
+      next = draw->pipeline.wide_line;
+      precalc_flat = 1;
+   }
+
+   if (wide_points || draw->rasterizer->point_sprite) {
+      draw->pipeline.wide_point->next = next;
+      next = draw->pipeline.wide_point;
+   }
+
+   if (draw->rasterizer->line_stipple_enable && draw->line_stipple) {
+      draw->pipeline.stipple->next = next;
+      next = draw->pipeline.stipple;
+      precalc_flat = 1;                /* only needed for lines really */
+   }
+
+   if (draw->rasterizer->poly_stipple_enable
+       && draw->pipeline.pstipple) {
+      draw->pipeline.pstipple->next = next;
+      next = draw->pipeline.pstipple;
+   }
+
+   if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
+       draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
+      draw->pipeline.unfilled->next = next;
+      next = draw->pipeline.unfilled;
+      precalc_flat = 1;                /* only needed for triangles really */
+      need_det = 1;
+   }
+
+   if (draw->rasterizer->flatshade && precalc_flat) {
+      draw->pipeline.flatshade->next = next;
+      next = draw->pipeline.flatshade;
+   }
+        
+   if (draw->rasterizer->offset_cw ||
+       draw->rasterizer->offset_ccw) {
+      draw->pipeline.offset->next = next;
+      next = draw->pipeline.offset;
+      need_det = 1;
+   }
+
+   if (draw->rasterizer->light_twoside) {
+      draw->pipeline.twoside->next = next;
+      next = draw->pipeline.twoside;
+      need_det = 1;
+   }
+
+   /* Always run the cull stage as we calculate determinant there
+    * also.  
+    *
+    * This can actually be a win as culling out the triangles can lead
+    * to less work emitting vertices, smaller vertex buffers, etc.
+    * It's difficult to say whether this will be true in general.
+    */
+   if (need_det || draw->rasterizer->cull_mode) {
+      draw->pipeline.cull->next = next;
+      next = draw->pipeline.cull;
+   }
+
+   /* Clip stage
+    */
+   if (!draw->rasterizer->bypass_clipping)
+   {
+      draw->pipeline.clip->next = next;
+      next = draw->pipeline.clip;
+   }
+
+   
+   draw->pipeline.first = next;
+   return next;
+}
+
+static void validate_tri( struct draw_stage *stage, 
+                         struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->tri( pipeline, header );
+}
+
+static void validate_line( struct draw_stage *stage, 
+                          struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->line( pipeline, header );
+}
+
+static void validate_point( struct draw_stage *stage, 
+                           struct prim_header *header )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->point( pipeline, header );
+}
+
+static void validate_reset_stipple_counter( struct draw_stage *stage )
+{
+   struct draw_stage *pipeline = validate_pipeline( stage );
+   pipeline->reset_stipple_counter( pipeline );
+}
+
+static void validate_flush( struct draw_stage *stage, 
+                           unsigned flags )
+{
+   /* May need to pass a backend flush on to the rasterize stage.
+    */
+   if (stage->next)
+      stage->next->flush( stage->next, flags );
+}
+
+
+static void validate_destroy( struct draw_stage *stage )
+{
+   FREE( stage );
+}
+
+
+/**
+ * Create validate pipeline stage.
+ */
+struct draw_stage *draw_validate_stage( struct draw_context *draw )
+{
+   struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
+
+   stage->draw = draw;
+   stage->next = NULL;
+   stage->point = validate_point;
+   stage->line = validate_line;
+   stage->tri = validate_tri;
+   stage->flush = validate_flush;
+   stage->reset_stipple_counter = validate_reset_stipple_counter;
+   stage->destroy = validate_destroy;
+
+   return stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_vbuf.c b/src/gallium/auxiliary/draw/draw_pipe_vbuf.c
new file mode 100644 (file)
index 0000000..30dceeb
--- /dev/null
@@ -0,0 +1,529 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * \file
+ * Vertex buffer drawing stage.
+ * 
+ * \author José Fonseca <jrfonsec@tungstengraphics.com>
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "pipe/p_debug.h"
+#include "pipe/p_util.h"
+
+#include "draw_vbuf.h"
+#include "draw_private.h"
+#include "draw_vertex.h"
+#include "translate/translate.h"
+
+
+/**
+ * Vertex buffer emit stage.
+ */
+struct vbuf_stage {
+   struct draw_stage stage; /**< This must be first (base class) */
+
+   struct vbuf_render *render;
+   
+   const struct vertex_info *vinfo;
+   
+   /** Vertex size in bytes */
+   unsigned vertex_size;
+
+   struct translate *translate;
+   
+   /* FIXME: we have no guarantee that 'unsigned' is 32bit */
+
+   /** Vertices in hardware format */
+   unsigned *vertices;
+   unsigned *vertex_ptr;
+   unsigned max_vertices;
+   unsigned nr_vertices;
+   
+   /** Indices */
+   ushort *indices;
+   unsigned max_indices;
+   unsigned nr_indices;
+
+   /* Cache point size somewhere it's address won't change:
+    */
+   float point_size;
+};
+
+
+/**
+ * Basically a cast wrapper.
+ */
+static INLINE struct vbuf_stage *
+vbuf_stage( struct draw_stage *stage )
+{
+   assert(stage);
+   return (struct vbuf_stage *)stage;
+}
+
+
+static void vbuf_flush_indices( struct vbuf_stage *vbuf );
+static void vbuf_flush_vertices( struct vbuf_stage *vbuf );
+static void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
+
+
+static INLINE boolean 
+overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )
+{
+   unsigned long used = (unsigned long) ((char *)ptr - (char *)map);
+   return (used + bytes) > bufsz;
+}
+
+
+static INLINE void 
+check_space( struct vbuf_stage *vbuf, unsigned nr )
+{
+   if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
+      vbuf_flush_vertices(vbuf);
+      vbuf_alloc_vertices(vbuf);
+   }
+
+   if (vbuf->nr_indices + nr > vbuf->max_indices )
+      vbuf_flush_indices(vbuf);
+}
+
+
+static INLINE void
+dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data)
+{
+//   assert(vinfo == vbuf->render->get_vertex_info(vbuf->render));
+   unsigned i, j;
+
+   for (i = 0; i < vinfo->num_attribs; i++) {
+      j = vinfo->src_index[i];
+      switch (vinfo->emit[i]) {
+      case EMIT_OMIT:
+         debug_printf("EMIT_OMIT:");
+         break;
+      case EMIT_1F:
+         debug_printf("EMIT_1F:\t");
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         break;
+      case EMIT_1F_PSIZE:
+         debug_printf("EMIT_1F_PSIZE:\t");
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         break;
+      case EMIT_2F:
+         debug_printf("EMIT_2F:\t");
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         break;
+      case EMIT_3F:
+         debug_printf("EMIT_3F:\t");
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         data += sizeof(float);
+         break;
+      case EMIT_4F:
+         debug_printf("EMIT_4F:\t");
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         debug_printf("%f ", *(float *)data); data += sizeof(float);
+         break;
+      case EMIT_4UB:
+         debug_printf("EMIT_4UB:\t");
+         debug_printf("%u ", *data++);
+         debug_printf("%u ", *data++);
+         debug_printf("%u ", *data++);
+         debug_printf("%u ", *data++);
+         break;
+      default:
+         assert(0);
+      }
+      debug_printf("\n");
+   }
+   debug_printf("\n");
+}
+
+
+/**
+ * Extract the needed fields from post-transformed vertex and emit
+ * a hardware(driver) vertex.
+ * Recall that the vertices are constructed by the 'draw' module and
+ * have a couple of slots at the beginning (1-dword header, 4-dword
+ * clip pos) that we ignore here.  We only use the vertex->data[] fields.
+ */
+static INLINE ushort 
+emit_vertex( struct vbuf_stage *vbuf,
+             struct vertex_header *vertex )
+{
+   if(vertex->vertex_id == UNDEFINED_VERTEX_ID) {      
+      /* Hmm - vertices are emitted one at a time - better make sure
+       * set_buffer is efficient.  Consider a special one-shot mode for
+       * translate.
+       */
+      vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0);
+      vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr);
+
+      if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr);
+      
+      vbuf->vertex_ptr += vbuf->vertex_size/4;
+      vertex->vertex_id = vbuf->nr_vertices++;
+   }
+
+   return vertex->vertex_id;
+}
+
+
+static void 
+vbuf_tri( struct draw_stage *stage,
+          struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+   unsigned i;
+
+   check_space( vbuf, 3 );
+
+   for (i = 0; i < 3; i++) {
+      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
+   }
+}
+
+
+static void 
+vbuf_line( struct draw_stage *stage, 
+           struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+   unsigned i;
+
+   check_space( vbuf, 2 );
+
+   for (i = 0; i < 2; i++) {
+      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
+   }   
+}
+
+
+static void 
+vbuf_point( struct draw_stage *stage, 
+            struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   check_space( vbuf, 1 );
+
+   vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] );
+}
+
+
+
+
+/**
+ * Set the prim type for subsequent vertices.
+ * This may result in a new vertex size.  The existing vbuffer (if any)
+ * will be flushed if needed and a new one allocated.
+ */
+static void
+vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
+{
+   struct translate_key hw_key;
+   unsigned dst_offset;
+   unsigned i;
+
+   vbuf->render->set_primitive(vbuf->render, prim);
+
+   /* Must do this after set_primitive() above:
+    * 
+    * XXX: need some state managment to track when this needs to be
+    * recalculated.  The driver should tell us whether there was a
+    * state change.
+    */
+   vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
+
+   if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) {
+      vbuf_flush_vertices(vbuf);
+      vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
+   }
+
+   /* Translate from pipeline vertices to hw vertices.
+    */
+   dst_offset = 0;
+   memset(&hw_key, 0, sizeof(hw_key));
+
+   for (i = 0; i < vbuf->vinfo->num_attribs; i++) {
+      unsigned emit_sz = 0;
+      unsigned src_buffer = 0;
+      unsigned output_format;
+      unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) );
+
+      switch (vbuf->vinfo->emit[i]) {
+      case EMIT_4F:
+        output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+        emit_sz = 4 * sizeof(float);
+        break;
+      case EMIT_3F:
+        output_format = PIPE_FORMAT_R32G32B32_FLOAT;
+        emit_sz = 3 * sizeof(float);
+        break;
+      case EMIT_2F:
+        output_format = PIPE_FORMAT_R32G32_FLOAT;
+        emit_sz = 2 * sizeof(float);
+        break;
+      case EMIT_1F:
+        output_format = PIPE_FORMAT_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+        break;
+      case EMIT_1F_PSIZE:
+        output_format = PIPE_FORMAT_R32_FLOAT;
+        emit_sz = 1 * sizeof(float);
+        src_buffer = 1;
+        src_offset = 0;
+        break;
+      case EMIT_4UB:
+        output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
+        emit_sz = 4 * sizeof(ubyte);
+      default:
+        assert(0);
+        output_format = PIPE_FORMAT_NONE;
+        emit_sz = 0;
+        break;
+      }
+      
+      hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+      hw_key.element[i].input_buffer = src_buffer;
+      hw_key.element[i].input_offset = src_offset;
+      hw_key.element[i].output_format = output_format;
+      hw_key.element[i].output_offset = dst_offset;
+
+      dst_offset += emit_sz;
+   }
+
+   hw_key.nr_elements = vbuf->vinfo->num_attribs;
+   hw_key.output_stride = vbuf->vinfo->size * 4;
+
+   /* Don't bother with caching at this stage:
+    */
+   if (!vbuf->translate ||
+       memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) 
+   {
+      if (vbuf->translate)
+        vbuf->translate->release(vbuf->translate);
+
+      vbuf->translate = translate_create( &hw_key );
+
+      vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0);
+   }
+
+   vbuf->point_size = vbuf->stage.draw->rasterizer->point_size;
+
+   /* Allocate new buffer?
+    */
+   if (!vbuf->vertices)
+      vbuf_alloc_vertices(vbuf);
+}
+
+
+static void 
+vbuf_first_tri( struct draw_stage *stage,
+                struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   vbuf_flush_indices( vbuf );   
+   stage->tri = vbuf_tri;
+   vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);
+   stage->tri( stage, prim );
+}
+
+
+static void 
+vbuf_first_line( struct draw_stage *stage,
+                 struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   vbuf_flush_indices( vbuf );
+   stage->line = vbuf_line;
+   vbuf_set_prim(vbuf, PIPE_PRIM_LINES);
+   stage->line( stage, prim );
+}
+
+
+static void 
+vbuf_first_point( struct draw_stage *stage,
+                  struct prim_header *prim )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   vbuf_flush_indices( vbuf );
+   stage->point = vbuf_point;
+   vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);
+   stage->point( stage, prim );
+}
+
+
+static void 
+vbuf_flush_indices( struct vbuf_stage *vbuf ) 
+{
+   if(!vbuf->nr_indices)
+      return;
+   
+   assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == 
+          vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
+
+   vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
+   
+   vbuf->nr_indices = 0;
+}
+
+
+/**
+ * Flush existing vertex buffer and allocate a new one.
+ * 
+ * XXX: We separate flush-on-index-full and flush-on-vb-full, but may 
+ * raise issues uploading vertices if the hardware wants to flush when
+ * we flush.
+ */
+static void 
+vbuf_flush_vertices( struct vbuf_stage *vbuf )
+{
+   if(vbuf->vertices) {      
+      vbuf_flush_indices(vbuf);
+      
+      /* Reset temporary vertices ids */
+      if(vbuf->nr_vertices)
+        draw_reset_vertex_ids( vbuf->stage.draw );
+      
+      /* Free the vertex buffer */
+      vbuf->render->release_vertices(vbuf->render,
+                                     vbuf->vertices,
+                                     vbuf->vertex_size,
+                                     vbuf->nr_vertices);
+      vbuf->max_vertices = vbuf->nr_vertices = 0;
+      vbuf->vertex_ptr = vbuf->vertices = NULL;
+      
+   }
+}
+   
+
+static void 
+vbuf_alloc_vertices( struct vbuf_stage *vbuf )
+{
+   assert(!vbuf->nr_indices);
+   assert(!vbuf->vertices);
+   
+   /* Allocate a new vertex buffer */
+   vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
+   vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
+                                                            (ushort) vbuf->vertex_size,
+                                                            (ushort) vbuf->max_vertices);
+   vbuf->vertex_ptr = vbuf->vertices;
+}
+
+
+
+static void 
+vbuf_flush( struct draw_stage *stage, unsigned flags )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   vbuf_flush_indices( vbuf );
+
+   stage->point = vbuf_first_point;
+   stage->line = vbuf_first_line;
+   stage->tri = vbuf_first_tri;
+
+   if (flags & DRAW_FLUSH_BACKEND)
+      vbuf_flush_vertices( vbuf );
+}
+
+
+static void 
+vbuf_reset_stipple_counter( struct draw_stage *stage )
+{
+   /* XXX: Need to do something here for hardware with linestipple.
+    */
+   (void) stage;
+}
+
+
+static void vbuf_destroy( struct draw_stage *stage )
+{
+   struct vbuf_stage *vbuf = vbuf_stage( stage );
+
+   if(vbuf->indices)
+      align_free( vbuf->indices );
+   
+   if(vbuf->translate)
+      vbuf->translate->release( vbuf->translate );
+
+   if (vbuf->render)
+      vbuf->render->destroy( vbuf->render );
+
+   FREE( stage );
+}
+
+
+/**
+ * Create a new primitive vbuf/render stage.
+ */
+struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
+                                    struct vbuf_render *render )
+{
+   struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
+
+   if(!vbuf)
+      goto fail;
+   
+   vbuf->stage.draw = draw;
+   vbuf->stage.point = vbuf_first_point;
+   vbuf->stage.line = vbuf_first_line;
+   vbuf->stage.tri = vbuf_first_tri;
+   vbuf->stage.flush = vbuf_flush;
+   vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
+   vbuf->stage.destroy = vbuf_destroy;
+   
+   vbuf->render = render;
+   vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1);
+
+   vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * 
+                                           sizeof(vbuf->indices[0]), 
+                                           16 );
+   if(!vbuf->indices)
+      goto fail;
+   
+   vbuf->vertices = NULL;
+   vbuf->vertex_ptr = vbuf->vertices;
+   
+   return &vbuf->stage;
+
+ fail:
+   if (vbuf)
+      vbuf_destroy(&vbuf->stage);
+   
+   return NULL;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_line.c b/src/gallium/auxiliary/draw/draw_pipe_wide_line.c
new file mode 100644 (file)
index 0000000..9a168ce
--- /dev/null
@@ -0,0 +1,190 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_private.h"
+
+
+struct wideline_stage {
+   struct draw_stage stage;
+
+   float half_line_width;
+};
+
+
+
+static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage )
+{
+   return (struct wideline_stage *)stage;
+}
+
+
+static void wideline_point( struct draw_stage *stage,
+                               struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+
+static void wideline_tri( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+/**
+ * Draw a wide line by drawing a quad (two triangles).
+ * XXX need to disable polygon stipple.
+ */
+static void wideline_line( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   /*const struct wideline_stage *wide = wideline_stage(stage);*/
+   const float half_width = 0.5f * stage->draw->rasterizer->line_width;
+
+   struct prim_header tri;
+
+   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
+   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
+   struct vertex_header *v2 = dup_vert(stage, header->v[1], 2);
+   struct vertex_header *v3 = dup_vert(stage, header->v[1], 3);
+
+   float *pos0 = v0->data[0];
+   float *pos1 = v1->data[0];
+   float *pos2 = v2->data[0];
+   float *pos3 = v3->data[0];
+
+   const float dx = FABSF(pos0[0] - pos2[0]);
+   const float dy = FABSF(pos0[1] - pos2[1]);
+
+   /* small tweak to meet GL specification */
+   const float bias = 0.125f;
+
+   /*
+    * Draw wide line as a quad (two tris) by "stretching" the line along
+    * X or Y.
+    * We need to tweak coords in several ways to be conformant here.
+    */
+
+   if (dx > dy) {
+      /* x-major line */
+      pos0[1] = pos0[1] - half_width - bias;
+      pos1[1] = pos1[1] + half_width - bias;
+      pos2[1] = pos2[1] - half_width - bias;
+      pos3[1] = pos3[1] + half_width - bias;
+      if (pos0[0] < pos2[0]) {
+         /* left to right line */
+         pos0[0] -= 0.5f;
+         pos1[0] -= 0.5f;
+         pos2[0] -= 0.5f;
+         pos3[0] -= 0.5f;
+      }
+      else {
+         /* right to left line */
+         pos0[0] += 0.5f;
+         pos1[0] += 0.5f;
+         pos2[0] += 0.5f;
+         pos3[0] += 0.5f;
+      }
+   }
+   else {
+      /* y-major line */
+      pos0[0] = pos0[0] - half_width + bias;
+      pos1[0] = pos1[0] + half_width + bias;
+      pos2[0] = pos2[0] - half_width + bias;
+      pos3[0] = pos3[0] + half_width + bias;
+      if (pos0[1] < pos2[1]) {
+         /* top to bottom line */
+         pos0[1] -= 0.5f;
+         pos1[1] -= 0.5f;
+         pos2[1] -= 0.5f;
+         pos3[1] -= 0.5f;
+      }
+      else {
+         /* bottom to top line */
+         pos0[1] += 0.5f;
+         pos1[1] += 0.5f;
+         pos2[1] += 0.5f;
+         pos3[1] += 0.5f;
+      }
+   }
+
+   tri.det = header->det;  /* only the sign matters */
+   tri.v[0] = v0;
+   tri.v[1] = v2;
+   tri.v[2] = v3;
+   stage->next->tri( stage->next, &tri );
+
+   tri.v[0] = v0;
+   tri.v[1] = v3;
+   tri.v[2] = v1;
+   stage->next->tri( stage->next, &tri );
+}
+
+
+static void wideline_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void wideline_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void wideline_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
+{
+   struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage);
+
+   draw_alloc_temp_verts( &wide->stage, 4 );
+
+   wide->stage.draw = draw;
+   wide->stage.next = NULL;
+   wide->stage.point = wideline_point;
+   wide->stage.line = wideline_line;
+   wide->stage.tri = wideline_tri;
+   wide->stage.flush = wideline_flush;
+   wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
+   wide->stage.destroy = wideline_destroy;
+
+   return &wide->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
new file mode 100644 (file)
index 0000000..3d0add0
--- /dev/null
@@ -0,0 +1,281 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_vs.h"
+
+
+struct widepoint_stage {
+   struct draw_stage stage;
+
+   float half_point_size;
+   float point_size_min;
+   float point_size_max;
+
+   float xbias;
+   float ybias;
+
+   uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
+   uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
+   uint num_texcoords;
+
+   int psize_slot;
+};
+
+
+
+static INLINE struct widepoint_stage *
+widepoint_stage( struct draw_stage *stage )
+{
+   return (struct widepoint_stage *)stage;
+}
+
+
+static void passthrough_point( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+static void widepoint_line( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   stage->next->line(stage->next, header);
+}
+
+static void widepoint_tri( struct draw_stage *stage,
+                           struct prim_header *header )
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+/**
+ * Set the vertex texcoords for sprite mode.
+ * Coords may be left untouched or set to a right-side-up or upside-down
+ * orientation.
+ */
+static void set_texcoords(const struct widepoint_stage *wide,
+                          struct vertex_header *v, const float tc[4])
+{
+   uint i;
+   for (i = 0; i < wide->num_texcoords; i++) {
+      if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
+         uint j = wide->texcoord_slot[i];
+         v->data[j][0] = tc[0];
+         if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
+            v->data[j][1] = 1.0f - tc[1];
+         else
+            v->data[j][1] = tc[1];
+         v->data[j][2] = tc[2];
+         v->data[j][3] = tc[3];
+      }
+   }
+}
+
+
+/* If there are lots of sprite points (and why wouldn't there be?) it
+ * would probably be more sensible to change hardware setup to
+ * optimize this rather than doing the whole thing in software like
+ * this.
+ */
+static void widepoint_point( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   const struct widepoint_stage *wide = widepoint_stage(stage);
+   const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
+   float half_size;
+   float left_adj, right_adj, bot_adj, top_adj;
+
+   struct prim_header tri;
+
+   /* four dups of original vertex */
+   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
+   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
+   struct vertex_header *v2 = dup_vert(stage, header->v[0], 2);
+   struct vertex_header *v3 = dup_vert(stage, header->v[0], 3);
+
+   float *pos0 = v0->data[0];
+   float *pos1 = v1->data[0];
+   float *pos2 = v2->data[0];
+   float *pos3 = v3->data[0];
+
+   /* point size is either per-vertex or fixed size */
+   if (wide->psize_slot >= 0) {
+      half_size = header->v[0]->data[wide->psize_slot][0];
+
+      /* XXX: temporary -- do this in the vertex shader??
+       */
+      half_size = CLAMP(half_size,
+                        wide->point_size_min,
+                        wide->point_size_max);
+      
+      half_size *= 0.5f; 
+   }
+   else {
+      half_size = wide->half_point_size;
+   }
+
+   left_adj = -half_size + wide->xbias;
+   right_adj = half_size + wide->xbias;
+   bot_adj = half_size + wide->ybias;
+   top_adj = -half_size + wide->ybias;
+
+   pos0[0] += left_adj;
+   pos0[1] += top_adj;
+
+   pos1[0] += left_adj;
+   pos1[1] += bot_adj;
+
+   pos2[0] += right_adj;
+   pos2[1] += top_adj;
+
+   pos3[0] += right_adj;
+   pos3[1] += bot_adj;
+
+   if (sprite) {
+      static const float tex00[4] = { 0, 0, 0, 1 };
+      static const float tex01[4] = { 0, 1, 0, 1 };
+      static const float tex11[4] = { 1, 1, 0, 1 };
+      static const float tex10[4] = { 1, 0, 0, 1 };
+      set_texcoords( wide, v0, tex00 );
+      set_texcoords( wide, v1, tex01 );
+      set_texcoords( wide, v2, tex10 );
+      set_texcoords( wide, v3, tex11 );
+   }
+
+   tri.det = header->det;  /* only the sign matters */
+   tri.v[0] = v0;
+   tri.v[1] = v2;
+   tri.v[2] = v3;
+   stage->next->tri( stage->next, &tri );
+
+   tri.v[0] = v0;
+   tri.v[1] = v3;
+   tri.v[2] = v1;
+   stage->next->tri( stage->next, &tri );
+}
+
+
+static void widepoint_first_point( struct draw_stage *stage, 
+                             struct prim_header *header )
+{
+   struct widepoint_stage *wide = widepoint_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   wide->half_point_size = 0.5f * draw->rasterizer->point_size;
+   wide->point_size_min = draw->rasterizer->point_size_min;
+   wide->point_size_max = draw->rasterizer->point_size_max;
+   wide->xbias = 0.0;
+   wide->ybias = 0.0;
+
+   if (draw->rasterizer->gl_rasterization_rules) {
+      wide->xbias = 0.125;
+   }
+
+   /* XXX we won't know the real size if it's computed by the vertex shader! */
+   if ((draw->rasterizer->point_size > draw->wide_point_threshold) ||
+       (draw->rasterizer->point_sprite && draw->point_sprite)) {
+      stage->point = widepoint_point;
+   }
+   else {
+      stage->point = passthrough_point;
+   }
+
+   if (draw->rasterizer->point_sprite) {
+      /* find vertex shader texcoord outputs */
+      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      uint i, j = 0;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
+            wide->texcoord_slot[j] = i;
+            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
+            j++;
+         }
+      }
+      wide->num_texcoords = j;
+   }
+
+   wide->psize_slot = -1;
+   if (draw->rasterizer->point_size_per_vertex) {
+      /* find PSIZ vertex output */
+      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      uint i;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
+            wide->psize_slot = i;
+            break;
+         }
+      }
+   }
+   
+   stage->point( stage, header );
+}
+
+
+static void widepoint_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->point = widepoint_first_point;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void widepoint_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void widepoint_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+struct draw_stage *draw_wide_point_stage( struct draw_context *draw )
+{
+   struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage);
+
+   draw_alloc_temp_verts( &wide->stage, 4 );
+
+   wide->stage.draw = draw;
+   wide->stage.next = NULL;
+   wide->stage.point = widepoint_first_point;
+   wide->stage.line = widepoint_line;
+   wide->stage.tri = widepoint_tri;
+   wide->stage.flush = widepoint_flush;
+   wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter;
+   wide->stage.destroy = widepoint_destroy;
+
+   return &wide->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c b/src/gallium/auxiliary/draw/draw_pipe_wide_prims.c
new file mode 100644 (file)
index 0000000..d6bff11
--- /dev/null
@@ -0,0 +1,366 @@
+/**************************************************************************
+ * 
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * 
+ **************************************************************************/
+
+/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "pipe/p_util.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw_private.h"
+
+
+struct wide_stage {
+   struct draw_stage stage;
+
+   float half_line_width;
+   float half_point_size;
+
+   uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
+   uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
+   uint num_texcoords;
+
+   int psize_slot;
+};
+
+
+
+static INLINE struct wide_stage *wide_stage( struct draw_stage *stage )
+{
+   return (struct wide_stage *)stage;
+}
+
+
+static void passthrough_point( struct draw_stage *stage,
+                               struct prim_header *header )
+{
+   stage->next->point( stage->next, header );
+}
+
+static void passthrough_line( struct draw_stage *stage,
+                              struct prim_header *header )
+{
+   stage->next->line(stage->next, header);
+}
+
+static void passthrough_tri( struct draw_stage *stage,
+                             struct prim_header *header )
+{
+   stage->next->tri(stage->next, header);
+}
+
+
+/**
+ * Draw a wide line by drawing a quad (two triangles).
+ * XXX need to disable polygon stipple.
+ */
+static void wide_line( struct draw_stage *stage,
+                      struct prim_header *header )
+{
+   const struct wide_stage *wide = wide_stage(stage);
+   const float half_width = wide->half_line_width;
+
+   struct prim_header tri;
+
+   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
+   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
+   struct vertex_header *v2 = dup_vert(stage, header->v[1], 2);
+   struct vertex_header *v3 = dup_vert(stage, header->v[1], 3);
+
+   float *pos0 = v0->data[0];
+   float *pos1 = v1->data[0];
+   float *pos2 = v2->data[0];
+   float *pos3 = v3->data[0];
+
+   const float dx = FABSF(pos0[0] - pos2[0]);
+   const float dy = FABSF(pos0[1] - pos2[1]);
+   
+   /*
+    * Draw wide line as a quad (two tris) by "stretching" the line along
+    * X or Y.
+    * We need to tweak coords in several ways to be conformant here.
+    */
+
+   if (dx > dy) {
+      /* x-major line */
+      pos0[1] = pos0[1] - half_width - 0.25f;
+      pos1[1] = pos1[1] + half_width - 0.25f;
+      pos2[1] = pos2[1] - half_width - 0.25f;
+      pos3[1] = pos3[1] + half_width - 0.25f;
+      if (pos0[0] < pos2[0]) {
+         /* left to right line */
+         pos0[0] -= 0.5f;
+         pos1[0] -= 0.5f;
+         pos2[0] -= 0.5f;
+         pos3[0] -= 0.5f;
+      }
+      else {
+         /* right to left line */
+         pos0[0] += 0.5f;
+         pos1[0] += 0.5f;
+         pos2[0] += 0.5f;
+         pos3[0] += 0.5f;
+      }
+   }
+   else {
+      /* y-major line */
+      pos0[0] = pos0[0] - half_width + 0.25f;
+      pos1[0] = pos1[0] + half_width + 0.25f;
+      pos2[0] = pos2[0] - half_width + 0.25f;
+      pos3[0] = pos3[0] + half_width + 0.25f;
+      if (pos0[1] < pos2[1]) {
+         /* top to bottom line */
+         pos0[1] -= 0.5f;
+         pos1[1] -= 0.5f;
+         pos2[1] -= 0.5f;
+         pos3[1] -= 0.5f;
+      }
+      else {
+         /* bottom to top line */
+         pos0[1] += 0.5f;
+         pos1[1] += 0.5f;
+         pos2[1] += 0.5f;
+         pos3[1] += 0.5f;
+      }
+   }
+
+   tri.det = header->det;  /* only the sign matters */
+   tri.v[0] = v0;
+   tri.v[1] = v2;
+   tri.v[2] = v3;
+   stage->next->tri( stage->next, &tri );
+
+   tri.v[0] = v0;
+   tri.v[1] = v3;
+   tri.v[2] = v1;
+   stage->next->tri( stage->next, &tri );
+}
+
+
+/**
+ * Set the vertex texcoords for sprite mode.
+ * Coords may be left untouched or set to a right-side-up or upside-down
+ * orientation.
+ */
+static void set_texcoords(const struct wide_stage *wide,
+                          struct vertex_header *v, const float tc[4])
+{
+   uint i;
+   for (i = 0; i < wide->num_texcoords; i++) {
+      if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
+         uint j = wide->texcoord_slot[i];
+         v->data[j][0] = tc[0];
+         if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
+            v->data[j][1] = 1.0f - tc[1];
+         else
+            v->data[j][1] = tc[1];
+         v->data[j][2] = tc[2];
+         v->data[j][3] = tc[3];
+      }
+   }
+}
+
+
+/* If there are lots of sprite points (and why wouldn't there be?) it
+ * would probably be more sensible to change hardware setup to
+ * optimize this rather than doing the whole thing in software like
+ * this.
+ */
+static void wide_point( struct draw_stage *stage,
+                       struct prim_header *header )
+{
+   const struct wide_stage *wide = wide_stage(stage);
+   const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
+   float half_size;
+   float left_adj, right_adj;
+
+   struct prim_header tri;
+
+   /* four dups of original vertex */
+   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
+   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
+   struct vertex_header *v2 = dup_vert(stage, header->v[0], 2);
+   struct vertex_header *v3 = dup_vert(stage, header->v[0], 3);
+
+   float *pos0 = v0->data[0];
+   float *pos1 = v1->data[0];
+   float *pos2 = v2->data[0];
+   float *pos3 = v3->data[0];
+
+   /* point size is either per-vertex or fixed size */
+   if (wide->psize_slot >= 0) {
+      half_size = 0.5f * header->v[0]->data[wide->psize_slot][0];
+   }
+   else {
+      half_size = wide->half_point_size;
+   }
+
+   left_adj = -half_size; /* + 0.25f;*/
+   right_adj = half_size; /* + 0.25f;*/
+
+   pos0[0] += left_adj;
+   pos0[1] -= half_size;
+
+   pos1[0] += left_adj;
+   pos1[1] += half_size;
+
+   pos2[0] += right_adj;
+   pos2[1] -= half_size;
+
+   pos3[0] += right_adj;
+   pos3[1] += half_size;
+
+   if (sprite) {
+      static const float tex00[4] = { 0, 0, 0, 1 };
+      static const float tex01[4] = { 0, 1, 0, 1 };
+      static const float tex11[4] = { 1, 1, 0, 1 };
+      static const float tex10[4] = { 1, 0, 0, 1 };
+      set_texcoords( wide, v0, tex00 );
+      set_texcoords( wide, v1, tex01 );
+      set_texcoords( wide, v2, tex10 );
+      set_texcoords( wide, v3, tex11 );
+   }
+
+   tri.det = header->det;  /* only the sign matters */
+   tri.v[0] = v0;
+   tri.v[1] = v2;
+   tri.v[2] = v3;
+   stage->next->tri( stage->next, &tri );
+
+   tri.v[0] = v0;
+   tri.v[1] = v3;
+   tri.v[2] = v1;
+   stage->next->tri( stage->next, &tri );
+}
+
+
+static void wide_first_point( struct draw_stage *stage, 
+                             struct prim_header *header )
+{
+   struct wide_stage *wide = wide_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   wide->half_point_size = 0.5f * draw->rasterizer->point_size;
+
+   /* XXX we won't know the real size if it's computed by the vertex shader! */
+   if (draw->rasterizer->point_size > draw->wide_point_threshold) {
+      stage->point = wide_point;
+   }
+   else {
+      stage->point = passthrough_point;
+   }
+
+   if (draw->rasterizer->point_sprite) {
+      /* find vertex shader texcoord outputs */
+      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      uint i, j = 0;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
+            wide->texcoord_slot[j] = i;
+            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
+            j++;
+         }
+      }
+      wide->num_texcoords = j;
+   }
+
+   wide->psize_slot = -1;
+
+   if (draw->rasterizer->point_size_per_vertex) {
+      /* find PSIZ vertex output */
+      const struct draw_vertex_shader *vs = draw->vertex_shader;
+      uint i;
+      for (i = 0; i < vs->info.num_outputs; i++) {
+         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
+            wide->psize_slot = i;
+            break;
+         }
+      }
+   }
+   
+   stage->point( stage, header );
+}
+
+
+
+static void wide_first_line( struct draw_stage *stage,
+                            struct prim_header *header )
+{
+   struct wide_stage *wide = wide_stage(stage);
+   struct draw_context *draw = stage->draw;
+
+   wide->half_line_width = 0.5f * draw->rasterizer->line_width;
+
+   if (draw->rasterizer->line_width != 1.0) {
+      wide->stage.line = wide_line;
+   }
+   else {
+      wide->stage.line = passthrough_line;
+   }
+   
+   stage->line( stage, header );
+}
+
+
+static void wide_flush( struct draw_stage *stage, unsigned flags )
+{
+   stage->line = wide_first_line;
+   stage->point = wide_first_point;
+   stage->next->flush( stage->next, flags );
+}
+
+
+static void wide_reset_stipple_counter( struct draw_stage *stage )
+{
+   stage->next->reset_stipple_counter( stage->next );
+}
+
+
+static void wide_destroy( struct draw_stage *stage )
+{
+   draw_free_temp_verts( stage );
+   FREE( stage );
+}
+
+
+struct draw_stage *draw_wide_stage( struct draw_context *draw )
+{
+   struct wide_stage *wide = CALLOC_STRUCT(wide_stage);
+
+   draw_alloc_temp_verts( &wide->stage, 4 );
+
+   wide->stage.draw = draw;
+   wide->stage.next = NULL;
+   wide->stage.point = wide_first_point;
+   wide->stage.line = wide_first_line;
+   wide->stage.tri = passthrough_tri;
+   wide->stage.flush = wide_flush;
+   wide->stage.reset_stipple_counter = wide_reset_stipple_counter;
+   wide->stage.destroy = wide_destroy;
+
+   return &wide->stage;
+}
diff --git a/src/gallium/auxiliary/draw/draw_pstipple.c b/src/gallium/auxiliary/draw/draw_pstipple.c
deleted file mode 100644 (file)
index 4dddb72..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * Polygon stipple stage:  implement polygon stipple with texture map and
- * fragment program.  The fragment program samples the texture and does
- * a fragment kill for the stipple-failing fragments.
- *
- * Authors:  Brian Paul
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_inlines.h"
-#include "pipe/p_context.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-
-#include "tgsi/util/tgsi_transform.h"
-#include "tgsi/util/tgsi_dump.h"
-
-#include "draw_context.h"
-#include "draw_private.h"
-
-
-
-/**
- * Subclass of pipe_shader_state to carry extra fragment shader info.
- */
-struct pstip_fragment_shader
-{
-   struct pipe_shader_state state;
-   void *driver_fs;
-   void *pstip_fs;
-   uint sampler_unit;
-};
-
-
-/**
- * Subclass of draw_stage
- */
-struct pstip_stage
-{
-   struct draw_stage stage;
-
-   void *sampler_cso;
-   struct pipe_texture *texture;
-   uint num_samplers;
-   uint num_textures;
-
-   /*
-    * Currently bound state
-    */
-   struct pstip_fragment_shader *fs;
-   struct {
-      void *samplers[PIPE_MAX_SAMPLERS];
-      struct pipe_texture *textures[PIPE_MAX_SAMPLERS];
-      const struct pipe_poly_stipple *stipple;
-   } state;
-
-   /*
-    * Driver interface/override functions
-    */
-   void * (*driver_create_fs_state)(struct pipe_context *,
-                                    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 *, unsigned, void **);
-
-   void (*driver_set_sampler_textures)(struct pipe_context *, unsigned,
-                                       struct pipe_texture **);
-
-   void (*driver_set_polygon_stipple)(struct pipe_context *,
-                                      const struct pipe_poly_stipple *);
-
-   struct pipe_context *pipe;
-};
-
-
-
-/**
- * Subclass of tgsi_transform_context, used for transforming the
- * user's fragment shader to add the special AA instructions.
- */
-struct pstip_transform_context {
-   struct tgsi_transform_context base;
-   uint tempsUsed;  /**< bitmask */
-   int wincoordInput;
-   int maxInput;
-   uint samplersUsed;  /**< bitfield of samplers used */
-   int freeSampler;  /** an available sampler for the pstipple */
-   int texTemp;  /**< temp registers */
-   int numImmed;
-   boolean firstInstruction;
-};
-
-
-/**
- * TGSI declaration transform callback.
- * Look for a free sampler, a free input attrib, and two free temp regs.
- */
-static void
-pstip_transform_decl(struct tgsi_transform_context *ctx,
-                     struct tgsi_full_declaration *decl)
-{
-   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
-
-   if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
-      uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
-         pctx->samplersUsed |= 1 << i;
-      }
-   }
-   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
-      pctx->maxInput = MAX2(pctx->maxInput, (int) decl->u.DeclarationRange.Last);
-      if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION)
-         pctx->wincoordInput = (int) decl->u.DeclarationRange.First;
-   }
-   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
-      uint i;
-      for (i = decl->u.DeclarationRange.First;
-           i <= decl->u.DeclarationRange.Last; i++) {
-         pctx->tempsUsed |= (1 << i);
-      }
-   }
-
-   ctx->emit_declaration(ctx, decl);
-}
-
-
-static void
-pstip_transform_immed(struct tgsi_transform_context *ctx,
-                      struct tgsi_full_immediate *immed)
-{
-   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
-   pctx->numImmed++;
-}
-
-
-/**
- * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
- */
-static int
-free_bit(uint bitfield)
-{
-   int i;
-   for (i = 0; i < 32; i++) {
-      if ((bitfield & (1 << i)) == 0)
-         return i;
-   }
-   return -1;
-}
-
-
-/**
- * TGSI instruction transform callback.
- * Replace writes to result.color w/ a temp reg.
- * Upon END instruction, insert texture sampling code for antialiasing.
- */
-static void
-pstip_transform_inst(struct tgsi_transform_context *ctx,
-                     struct tgsi_full_instruction *inst)
-{
-   struct pstip_transform_context *pctx = (struct pstip_transform_context *) ctx;
-
-   if (pctx->firstInstruction) {
-      /* emit our new declarations before the first instruction */
-
-      struct tgsi_full_declaration decl;
-      struct tgsi_full_instruction newInst;
-      uint i;
-      int wincoordInput;
-
-      /* find free sampler */
-      pctx->freeSampler = free_bit(pctx->samplersUsed);
-      if (pctx->freeSampler >= PIPE_MAX_SAMPLERS)
-         pctx->freeSampler = PIPE_MAX_SAMPLERS - 1;
-
-      if (pctx->wincoordInput < 0)
-         wincoordInput = pctx->maxInput + 1;
-      else
-         wincoordInput = pctx->wincoordInput;
-
-      /* find one free temp reg */
-      for (i = 0; i < 32; i++) {
-         if ((pctx->tempsUsed & (1 << i)) == 0) {
-            /* found a free temp */
-            if (pctx->texTemp < 0)
-               pctx->texTemp  = i;
-            else
-               break;
-         }
-      }
-      assert(pctx->texTemp >= 0);
-
-      if (pctx->wincoordInput < 0) {
-         /* declare new position input reg */
-         decl = tgsi_default_full_declaration();
-         decl.Declaration.File = TGSI_FILE_INPUT;
-         decl.Declaration.Semantic = 1;
-         decl.Semantic.SemanticName = TGSI_SEMANTIC_POSITION;
-         decl.Semantic.SemanticIndex = 0;
-         decl.Declaration.Interpolate = 1;
-         decl.Interpolation.Interpolate = TGSI_INTERPOLATE_LINEAR; /* XXX? */
-         decl.u.DeclarationRange.First = 
-            decl.u.DeclarationRange.Last = wincoordInput;
-         ctx->emit_declaration(ctx, &decl);
-      }
-
-      /* declare new sampler */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_SAMPLER;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = pctx->freeSampler;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* declare new temp regs */
-      decl = tgsi_default_full_declaration();
-      decl.Declaration.File = TGSI_FILE_TEMPORARY;
-      decl.u.DeclarationRange.First = 
-      decl.u.DeclarationRange.Last = pctx->texTemp;
-      ctx->emit_declaration(ctx, &decl);
-
-      /* emit immediate = {1/32, 1/32, 1, 1}
-       * The index/position of this immediate will be pctx->numImmed
-       */
-      {
-         static const float value[4] = { 1.0/32, 1.0/32, 1.0, 1.0 };
-         struct tgsi_full_immediate immed;
-         uint size = 4;
-         immed = tgsi_default_full_immediate();
-         immed.Immediate.Size = 1 + size; /* one for the token itself */
-         immed.u.ImmediateFloat32 = (struct tgsi_immediate_float32 *) value;
-         ctx->emit_immediate(ctx, &immed);
-      }
-
-      pctx->firstInstruction = FALSE;
-
-
-      /* 
-       * Insert new MUL/TEX/KILP instructions at start of program
-       * Take gl_FragCoord, divide by 32 (stipple size), sample the
-       * texture and kill fragment if needed.
-       *
-       * We'd like to use non-normalized texcoords to index into a RECT
-       * texture, but we can only use GL_REPEAT wrap mode with normalized
-       * texcoords.  Darn.
-       */
-
-      /* MUL texTemp, INPUT[wincoord], 1/32; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = wincoordInput;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_IMMEDIATE;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->numImmed;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* TEX texTemp, texTemp, sampler; */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
-      newInst.Instruction.NumDstRegs = 1;
-      newInst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullDstRegisters[0].DstRegister.Index = pctx->texTemp;
-      newInst.Instruction.NumSrcRegs = 2;
-      newInst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
-      newInst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
-      newInst.FullSrcRegisters[1].SrcRegister.Index = pctx->freeSampler;
-      ctx->emit_instruction(ctx, &newInst);
-
-      /* KILP texTemp;   # if texTemp < 0, KILL fragment */
-      newInst = tgsi_default_full_instruction();
-      newInst.Instruction.Opcode = TGSI_OPCODE_KILP;
-      newInst.Instruction.NumDstRegs = 0;
-      newInst.Instruction.NumSrcRegs = 1;
-      newInst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-      newInst.FullSrcRegisters[0].SrcRegister.Index = pctx->texTemp;
-      newInst.FullSrcRegisters[0].SrcRegister.Negate = 1;
-      ctx->emit_instruction(ctx, &newInst);
-   }
-
-   /* emit this instruction */
-   ctx->emit_instruction(ctx, inst);
-}
-
-
-/**
- * Generate the frag shader we'll use for doing polygon stipple.
- * This will be the user's shader prefixed with a TEX and KIL instruction.
- */
-static void
-generate_pstip_fs(struct pstip_stage *pstip)
-{
-   const struct pipe_shader_state *orig_fs = &pstip->fs->state;
-   /*struct draw_context *draw = pstip->stage.draw;*/
-   struct pipe_shader_state pstip_fs;
-   struct pstip_transform_context transform;
-
-#define MAX 1000
-
-   pstip_fs = *orig_fs; /* copy to init */
-   pstip_fs.tokens = MALLOC(sizeof(struct tgsi_token) * MAX);
-
-   memset(&transform, 0, sizeof(transform));
-   transform.wincoordInput = -1;
-   transform.maxInput = -1;
-   transform.texTemp = -1;
-   transform.firstInstruction = TRUE;
-   transform.base.transform_instruction = pstip_transform_inst;
-   transform.base.transform_declaration = pstip_transform_decl;
-   transform.base.transform_immediate = pstip_transform_immed;
-
-   tgsi_transform_shader(orig_fs->tokens,
-                         (struct tgsi_token *) pstip_fs.tokens,
-                         MAX, &transform.base);
-
-#if 0 /* DEBUG */
-   tgsi_dump(orig_fs->tokens, 0);
-   tgsi_dump(pstip_fs.tokens, 0);
-#endif
-
-   pstip->fs->sampler_unit = transform.freeSampler;
-   assert(pstip->fs->sampler_unit < PIPE_MAX_SAMPLERS);
-
-   pstip->fs->pstip_fs = pstip->driver_create_fs_state(pstip->pipe, &pstip_fs);
-}
-
-
-/**
- * Load texture image with current stipple pattern.
- */
-static void
-pstip_update_texture(struct pstip_stage *pstip)
-{
-   static const uint bit31 = 1 << 31;
-   struct pipe_context *pipe = pstip->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_surface *surface;
-   const uint *stipple = pstip->state.stipple->stipple;
-   uint i, j;
-   ubyte *data;
-
-   surface = screen->get_tex_surface(screen, pstip->texture, 0, 0, 0);
-   data = pipe_surface_map(surface);
-
-   /*
-    * Load alpha texture.
-    * Note: 0 means keep the fragment, 255 means kill it.
-    * We'll negate the texel value and use KILP which kills if value
-    * is negative.
-    */
-   for (i = 0; i < 32; i++) {
-      for (j = 0; j < 32; j++) {
-         if (stipple[i] & (bit31 >> j)) {
-            /* fragment "on" */
-            data[i * surface->pitch + j] = 0;
-         }
-         else {
-            /* fragment "off" */
-            data[i * surface->pitch + j] = 255;
-         }
-      }
-   }
-
-   /* unmap */
-   pipe_surface_unmap(surface);
-   pipe_surface_reference(&surface, NULL);
-   pipe->texture_update(pipe, pstip->texture, 0, 0x1);
-}
-
-
-/**
- * Create the texture map we'll use for stippling.
- */
-static void
-pstip_create_texture(struct pstip_stage *pstip)
-{
-   struct pipe_context *pipe = pstip->pipe;
-   struct pipe_screen *screen = pipe->screen;
-   struct pipe_texture texTemp;
-
-   memset(&texTemp, 0, sizeof(texTemp));
-   texTemp.target = PIPE_TEXTURE_2D;
-   texTemp.format = PIPE_FORMAT_U_A8; /* XXX verify supported by driver! */
-   texTemp.last_level = 0;
-   texTemp.width[0] = 32;
-   texTemp.height[0] = 32;
-   texTemp.depth[0] = 1;
-   texTemp.cpp = 1;
-
-   pstip->texture = screen->texture_create(screen, &texTemp);
-   assert(pstip->texture->refcount == 1);
-}
-
-
-/**
- * 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 void
-pstip_create_sampler(struct pstip_stage *pstip)
-{
-   struct pipe_sampler_state sampler;
-   struct pipe_context *pipe = pstip->pipe;
-
-   memset(&sampler, 0, sizeof(sampler));
-   sampler.wrap_s = PIPE_TEX_WRAP_REPEAT;
-   sampler.wrap_t = PIPE_TEX_WRAP_REPEAT;
-   sampler.wrap_r = PIPE_TEX_WRAP_REPEAT;
-   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
-   sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
-   sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
-   sampler.normalized_coords = 1;
-   sampler.min_lod = 0.0f;
-   sampler.max_lod = 0.0f;
-
-   pstip->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
-}
-
-
-/**
- * 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.
- */
-static void
-bind_pstip_fragment_shader(struct pstip_stage *pstip)
-{
-   if (!pstip->fs->pstip_fs) {
-      generate_pstip_fs(pstip);
-   }
-   pstip->driver_bind_fs_state(pstip->pipe, pstip->fs->pstip_fs);
-}
-
-
-
-static INLINE struct pstip_stage *
-pstip_stage( struct draw_stage *stage )
-{
-   return (struct pstip_stage *) stage;
-}
-
-
-static void
-passthrough_point(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->point(stage->next, header);
-}
-
-
-static void
-passthrough_line(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->line(stage->next, header);
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-
-static void
-pstip_first_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   struct pstip_stage *pstip = pstip_stage(stage);
-   struct pipe_context *pipe = pstip->pipe;
-   uint num_samplers;
-
-   assert(stage->draw->rasterizer->poly_stipple_enable);
-
-   /* bind our fragprog */
-   bind_pstip_fragment_shader(pstip);
-
-   /* how many samplers? */
-   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
-   num_samplers = MAX2(pstip->num_textures, pstip->num_samplers);
-   num_samplers = MAX2(num_samplers, pstip->fs->sampler_unit + 1);
-
-   /* plug in our sampler, texture */
-   pstip->state.samplers[pstip->fs->sampler_unit] = pstip->sampler_cso;
-   pipe_texture_reference(&pstip->state.textures[pstip->fs->sampler_unit],
-                          pstip->texture);
-
-   assert(num_samplers <= PIPE_MAX_SAMPLERS);
-
-   pstip->driver_bind_sampler_states(pipe, num_samplers, pstip->state.samplers);
-   pstip->driver_set_sampler_textures(pipe, num_samplers, pstip->state.textures);
-
-   /* now really draw first line */
-   stage->tri = passthrough_tri;
-   stage->tri(stage, header);
-}
-
-
-static void
-pstip_flush(struct draw_stage *stage, unsigned flags)
-{
-   /*struct draw_context *draw = stage->draw;*/
-   struct pstip_stage *pstip = pstip_stage(stage);
-   struct pipe_context *pipe = pstip->pipe;
-
-   stage->tri = pstip_first_tri;
-   stage->next->flush( stage->next, flags );
-
-   /* restore original frag shader */
-   pstip->driver_bind_fs_state(pipe, pstip->fs->driver_fs);
-
-   /* XXX restore original texture, sampler state */
-   pstip->driver_bind_sampler_states(pipe, pstip->num_samplers,
-                                     pstip->state.samplers);
-   pstip->driver_set_sampler_textures(pipe, pstip->num_textures,
-                                      pstip->state.textures);
-}
-
-
-static void
-pstip_reset_stipple_counter(struct draw_stage *stage)
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void
-pstip_destroy(struct draw_stage *stage)
-{
-   struct pstip_stage *pstip = pstip_stage(stage);
-
-   pstip->pipe->delete_sampler_state(pstip->pipe, pstip->sampler_cso);
-
-   pipe_texture_release(&pstip->texture);
-
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-static struct pstip_stage *
-draw_pstip_stage(struct draw_context *draw)
-{
-   struct pstip_stage *pstip = CALLOC_STRUCT(pstip_stage);
-
-   draw_alloc_temp_verts( &pstip->stage, 8 );
-
-   pstip->stage.draw = draw;
-   pstip->stage.next = NULL;
-   pstip->stage.point = passthrough_point;
-   pstip->stage.line = passthrough_line;
-   pstip->stage.tri = pstip_first_tri;
-   pstip->stage.flush = pstip_flush;
-   pstip->stage.reset_stipple_counter = pstip_reset_stipple_counter;
-   pstip->stage.destroy = pstip_destroy;
-
-   return pstip;
-}
-
-
-static struct pstip_stage *
-pstip_stage_from_pipe(struct pipe_context *pipe)
-{
-   struct draw_context *draw = (struct draw_context *) pipe->draw;
-   return pstip_stage(draw->pipeline.pstipple);
-}
-
-
-/**
- * This function overrides the driver's create_fs_state() function and
- * will typically be called by the state tracker.
- */
-static void *
-pstip_create_fs_state(struct pipe_context *pipe,
-                       const struct pipe_shader_state *fs)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   struct pstip_fragment_shader *aafs = CALLOC_STRUCT(pstip_fragment_shader);
-
-   if (aafs) {
-      aafs->state = *fs;
-
-      /* pass-through */
-      aafs->driver_fs = pstip->driver_create_fs_state(pstip->pipe, fs);
-   }
-
-   return aafs;
-}
-
-
-static void
-pstip_bind_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
-   /* save current */
-   pstip->fs = aafs;
-   /* pass-through */
-   pstip->driver_bind_fs_state(pstip->pipe,
-                               (aafs ? aafs->driver_fs : NULL));
-}
-
-
-static void
-pstip_delete_fs_state(struct pipe_context *pipe, void *fs)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   struct pstip_fragment_shader *aafs = (struct pstip_fragment_shader *) fs;
-   /* pass-through */
-   pstip->driver_delete_fs_state(pstip->pipe, aafs->driver_fs);
-   FREE(aafs);
-}
-
-
-static void
-pstip_bind_sampler_states(struct pipe_context *pipe,
-                          unsigned num, void **sampler)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   uint i;
-
-   /* save current */
-   memcpy(pstip->state.samplers, sampler, num * sizeof(void *));
-   for (i = num; i < PIPE_MAX_SAMPLERS; i++) {
-      pstip->state.samplers[i] = NULL;
-   }
-
-   pstip->num_samplers = num;
-   /* pass-through */
-   pstip->driver_bind_sampler_states(pstip->pipe, num, sampler);
-}
-
-
-static void
-pstip_set_sampler_textures(struct pipe_context *pipe,
-                           unsigned num, struct pipe_texture **texture)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   uint i;
-
-   /* save current */
-   for (i = 0; i < num; i++) {
-      pipe_texture_reference(&pstip->state.textures[i], texture[i]);
-   }
-   for (; i < PIPE_MAX_SAMPLERS; i++) {
-      pipe_texture_reference(&pstip->state.textures[i], NULL);
-   }
-
-   pstip->num_textures = num;
-
-   /* pass-through */
-   pstip->driver_set_sampler_textures(pstip->pipe, num, texture);
-}
-
-
-static void
-pstip_set_polygon_stipple(struct pipe_context *pipe,
-                          const struct pipe_poly_stipple *stipple)
-{
-   struct pstip_stage *pstip = pstip_stage_from_pipe(pipe);
-   /* save current */
-   pstip->state.stipple = stipple;
-   /* pass-through */
-   pstip->driver_set_polygon_stipple(pstip->pipe, stipple);
-
-   pstip_update_texture(pstip);
-}
-
-
-
-/**
- * Called by drivers that want to install this AA line prim stage
- * into the draw module's pipeline.  This will not be used if the
- * hardware has native support for AA lines.
- */
-void
-draw_install_pstipple_stage(struct draw_context *draw,
-                            struct pipe_context *pipe)
-{
-   struct pstip_stage *pstip;
-
-   pipe->draw = (void *) draw;
-
-   /*
-    * Create / install AA line drawing / prim stage
-    */
-   pstip = draw_pstip_stage( draw );
-   assert(pstip);
-   draw->pipeline.pstipple = &pstip->stage;
-
-   pstip->pipe = pipe;
-
-   /* create special texture, sampler state */
-   pstip_create_texture(pstip);
-   pstip_create_sampler(pstip);
-
-   /* save original driver functions */
-   pstip->driver_create_fs_state = pipe->create_fs_state;
-   pstip->driver_bind_fs_state = pipe->bind_fs_state;
-   pstip->driver_delete_fs_state = pipe->delete_fs_state;
-
-   pstip->driver_bind_sampler_states = pipe->bind_sampler_states;
-   pstip->driver_set_sampler_textures = pipe->set_sampler_textures;
-   pstip->driver_set_polygon_stipple = pipe->set_polygon_stipple;
-
-   /* override the driver's functions */
-   pipe->create_fs_state = pstip_create_fs_state;
-   pipe->bind_fs_state = pstip_bind_fs_state;
-   pipe->delete_fs_state = pstip_delete_fs_state;
-
-   pipe->bind_sampler_states = pstip_bind_sampler_states;
-   pipe->set_sampler_textures = pstip_set_sampler_textures;
-   pipe->set_polygon_stipple = pstip_set_polygon_stipple;
-}
diff --git a/src/gallium/auxiliary/draw/draw_stipple.c b/src/gallium/auxiliary/draw/draw_stipple.c
deleted file mode 100644 (file)
index 506f335..0000000
+++ /dev/null
@@ -1,239 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-/* Implement line stipple by cutting lines up into smaller lines.
- * There are hundreds of ways to implement line stipple, this is one
- * choice that should work in all situations, requires no state
- * manipulations, but with a penalty in terms of large amounts of
- * generated geometry.
- */
-
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_private.h"
-
-
-/** Subclass of draw_stage */
-struct stipple_stage {
-   struct draw_stage stage;
-   float counter;
-   uint pattern;
-   uint factor;
-};
-
-
-static INLINE struct stipple_stage *
-stipple_stage(struct draw_stage *stage)
-{
-   return (struct stipple_stage *) stage;
-}
-
-
-/**
- * Compute interpolated vertex attributes for 'dst' at position 't' 
- * between 'v0' and 'v1'.
- * XXX using linear interpolation for all attribs at this time.
- */
-static void
-screen_interp( struct draw_context *draw,
-               struct vertex_header *dst,
-               float t,
-               const struct vertex_header *v0, 
-               const struct vertex_header *v1 )
-{
-   uint attr;
-   for (attr = 0; attr < draw->num_vs_outputs; attr++) {
-      const float *val0 = v0->data[attr];
-      const float *val1 = v1->data[attr];
-      float *newv = dst->data[attr];
-      uint i;
-      for (i = 0; i < 4; i++) {
-         newv[i] = val0[i] + t * (val1[i] - val0[i]);
-      }
-   }
-}
-
-
-static void
-emit_segment(struct draw_stage *stage, struct prim_header *header,
-             float t0, float t1)
-{
-   struct vertex_header *v0new = dup_vert(stage, header->v[0], 0);
-   struct vertex_header *v1new = dup_vert(stage, header->v[1], 1);
-   struct prim_header newprim = *header;
-
-   if (t0 > 0.0) {
-      screen_interp( stage->draw, v0new, t0, header->v[0], header->v[1] );
-      newprim.v[0] = v0new;
-   }
-
-   if (t1 < 1.0) {
-      screen_interp( stage->draw, v1new, t1, header->v[0], header->v[1] );
-      newprim.v[1] = v1new;
-   }
-
-   stage->next->line( stage->next, &newprim );
-}
-
-
-static INLINE unsigned
-stipple_test(int counter, ushort pattern, int factor)
-{
-   int b = (counter / factor) & 0xf;
-   return (1 << b) & pattern;
-}
-
-
-static void
-stipple_line(struct draw_stage *stage, struct prim_header *header)
-{
-   struct stipple_stage *stipple = stipple_stage(stage);
-   struct vertex_header *v0 = header->v[0];
-   struct vertex_header *v1 = header->v[1];
-   const float *pos0 = v0->data[0];
-   const float *pos1 = v1->data[0];
-   float start = 0;
-   int state = 0;
-
-   float x0 = pos0[0];
-   float x1 = pos1[0];
-   float y0 = pos0[1];
-   float y1 = pos1[1];
-
-   float dx = x0 > x1 ? x0 - x1 : x1 - x0;
-   float dy = y0 > y1 ? y0 - y1 : y1 - y0;
-
-   float length = MAX2(dx, dy);
-   int i;
-
-   /* XXX ToDo: intead of iterating pixel-by-pixel, use a look-up table.
-    */
-   for (i = 0; i < length; i++) {
-      int result = stipple_test( (int) stipple->counter+i,
-                                 (ushort) stipple->pattern, stipple->factor );
-      if (result != state) {
-         /* changing from "off" to "on" or vice versa */
-        if (state) {
-           if (start != i) {
-               /* finishing an "on" segment */
-              emit_segment( stage, header, start / length, i / length );
-            }
-        }
-        else {
-            /* starting an "on" segment */
-           start = (float) i;
-        }
-        state = result;           
-      }
-   }
-
-   if (state && start < length)
-      emit_segment( stage, header, start / length, 1.0 );
-
-   stipple->counter += length;
-}
-
-
-static void
-reset_stipple_counter(struct draw_stage *stage)
-{
-   struct stipple_stage *stipple = stipple_stage(stage);
-   stipple->counter = 0;
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void
-stipple_first_line(struct draw_stage *stage, 
-                  struct prim_header *header)
-{
-   struct stipple_stage *stipple = stipple_stage(stage);
-   struct draw_context *draw = stage->draw;
-
-   stipple->pattern = draw->rasterizer->line_stipple_pattern;
-   stipple->factor = draw->rasterizer->line_stipple_factor + 1;
-
-   stage->line = stipple_line;
-   stage->line( stage, header );
-}
-
-
-static void
-stipple_flush(struct draw_stage *stage, unsigned flags)
-{
-   stage->line = stipple_first_line;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void
-passthrough_point(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void
-passthrough_tri(struct draw_stage *stage, struct prim_header *header)
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-static void 
-stipple_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create line stippler stage
- */
-struct draw_stage *draw_stipple_stage( struct draw_context *draw )
-{
-   struct stipple_stage *stipple = CALLOC_STRUCT(stipple_stage);
-
-   draw_alloc_temp_verts( &stipple->stage, 2 );
-
-   stipple->stage.draw = draw;
-   stipple->stage.next = NULL;
-   stipple->stage.point = passthrough_point;
-   stipple->stage.line = stipple_first_line;
-   stipple->stage.tri = passthrough_tri;
-   stipple->stage.reset_stipple_counter = reset_stipple_counter;
-   stipple->stage.flush = stipple_flush;
-   stipple->stage.destroy = stipple_destroy;
-
-   return &stipple->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_twoside.c b/src/gallium/auxiliary/draw/draw_twoside.c
deleted file mode 100644 (file)
index 01d905c..0000000
+++ /dev/null
@@ -1,203 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_vs.h"
-
-
-struct twoside_stage {
-   struct draw_stage stage;
-   float sign;         /**< +1 or -1 */
-   uint attrib_front0, attrib_back0;
-   uint attrib_front1, attrib_back1;
-};
-
-
-static INLINE struct twoside_stage *twoside_stage( struct draw_stage *stage )
-{
-   return (struct twoside_stage *)stage;
-}
-
-
-
-
-/**
- * Copy back color(s) to front color(s).
- */
-static INLINE struct vertex_header *
-copy_bfc( struct twoside_stage *twoside, 
-          const struct vertex_header *v,
-          unsigned idx )
-{   
-   struct vertex_header *tmp = dup_vert( &twoside->stage, v, idx );
-   
-   if (twoside->attrib_back0) {
-      COPY_4FV(tmp->data[twoside->attrib_front0],
-               tmp->data[twoside->attrib_back0]);
-   }
-   if (twoside->attrib_back1) {
-      COPY_4FV(tmp->data[twoside->attrib_front1],
-               tmp->data[twoside->attrib_back1]);
-   }
-
-   return tmp;
-}
-
-
-/* Twoside tri:
- */
-static void twoside_tri( struct draw_stage *stage,
-                        struct prim_header *header )
-{
-   struct twoside_stage *twoside = twoside_stage(stage);
-
-   if (header->det * twoside->sign < 0.0) {
-      /* this is a back-facing triangle */
-      struct prim_header tmp;
-
-      tmp.det = header->det;
-      tmp.edgeflags = header->edgeflags;
-      /* copy back attribs to front attribs */
-      tmp.v[0] = copy_bfc(twoside, header->v[0], 0);
-      tmp.v[1] = copy_bfc(twoside, header->v[1], 1);
-      tmp.v[2] = copy_bfc(twoside, header->v[2], 2);
-
-      stage->next->tri( stage->next, &tmp );
-   }
-   else {
-      stage->next->tri( stage->next, header );
-   }
-}
-
-
-static void twoside_line( struct draw_stage *stage,
-                      struct prim_header *header )
-{
-   /* pass-through */
-   stage->next->line( stage->next, header );
-}
-
-
-static void twoside_point( struct draw_stage *stage,
-                       struct prim_header *header )
-{
-   /* pass-through */
-   stage->next->point( stage->next, header );
-}
-
-
-static void twoside_first_tri( struct draw_stage *stage, 
-                              struct prim_header *header )
-{
-   struct twoside_stage *twoside = twoside_stage(stage);
-   const struct draw_vertex_shader *vs = stage->draw->vertex_shader;
-   uint i;
-
-   twoside->attrib_front0 = 0;
-   twoside->attrib_front1 = 0;
-   twoside->attrib_back0 = 0;
-   twoside->attrib_back1 = 0;
-
-   /* Find which vertex shader outputs are front/back colors */
-   for (i = 0; i < vs->info.num_outputs; i++) {
-      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
-         if (vs->info.output_semantic_index[i] == 0)
-            twoside->attrib_front0 = i;
-         else
-            twoside->attrib_front1 = i;
-      }
-      if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
-         if (vs->info.output_semantic_index[i] == 0)
-            twoside->attrib_back0 = i;
-         else
-            twoside->attrib_back1 = i;
-      }
-   }
-
-   if (!twoside->attrib_back0)
-      twoside->attrib_front0 = 0;
-
-   if (!twoside->attrib_back1)
-      twoside->attrib_front1 = 0;
-
-   /*
-    * We'll multiply the primitive's determinant by this sign to determine
-    * if the triangle is back-facing (negative).
-    * sign = -1 for CCW, +1 for CW
-    */
-   twoside->sign = (stage->draw->rasterizer->front_winding == PIPE_WINDING_CCW) ? -1.0f : 1.0f;
-
-   stage->tri = twoside_tri;
-   stage->tri( stage, header );
-}
-
-
-static void twoside_flush( struct draw_stage *stage, unsigned flags )
-{
-   stage->tri = twoside_first_tri;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void twoside_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void twoside_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create twoside pipeline stage.
- */
-struct draw_stage *draw_twoside_stage( struct draw_context *draw )
-{
-   struct twoside_stage *twoside = CALLOC_STRUCT(twoside_stage);
-
-   draw_alloc_temp_verts( &twoside->stage, 3 );
-
-   twoside->stage.draw = draw;
-   twoside->stage.next = NULL;
-   twoside->stage.point = twoside_point;
-   twoside->stage.line = twoside_line;
-   twoside->stage.tri = twoside_first_tri;
-   twoside->stage.flush = twoside_flush;
-   twoside->stage.reset_stipple_counter = twoside_reset_stipple_counter;
-   twoside->stage.destroy = twoside_destroy;
-
-   return &twoside->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_unfilled.c b/src/gallium/auxiliary/draw/draw_unfilled.c
deleted file mode 100644 (file)
index b07860c..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/**
- * \brief  Drawing stage for handling glPolygonMode(line/point).
- * Convert triangles to points or lines as needed.
- */
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "draw_private.h"
-
-
-struct unfilled_stage {
-   struct draw_stage stage;
-
-   /** [0] = front face, [1] = back face.
-    * legal values:  PIPE_POLYGON_MODE_FILL, PIPE_POLYGON_MODE_LINE,
-    * and PIPE_POLYGON_MODE_POINT,
-    */
-   unsigned mode[2];
-};
-
-
-static INLINE struct unfilled_stage *unfilled_stage( struct draw_stage *stage )
-{
-   return (struct unfilled_stage *)stage;
-}
-
-
-
-static void point( struct draw_stage *stage,
-                  struct vertex_header *v0 )
-{
-   struct prim_header tmp;
-   tmp.v[0] = v0;
-   stage->next->point( stage->next, &tmp );
-}
-
-static void line( struct draw_stage *stage,
-                 struct vertex_header *v0,
-                 struct vertex_header *v1 )
-{
-   struct prim_header tmp;
-   tmp.v[0] = v0;
-   tmp.v[1] = v1;
-   stage->next->line( stage->next, &tmp );
-}
-
-
-static void points( struct draw_stage *stage,
-                   struct prim_header *header )
-{
-   struct vertex_header *v0 = header->v[0];
-   struct vertex_header *v1 = header->v[1];
-   struct vertex_header *v2 = header->v[2];
-
-   if (header->edgeflags & 0x1) point( stage, v0 );
-   if (header->edgeflags & 0x2) point( stage, v1 );
-   if (header->edgeflags & 0x4) point( stage, v2 );
-}
-
-
-static void lines( struct draw_stage *stage,
-                  struct prim_header *header )
-{
-   struct vertex_header *v0 = header->v[0];
-   struct vertex_header *v1 = header->v[1];
-   struct vertex_header *v2 = header->v[2];
-
-#if 0
-   assert(((header->edgeflags & 0x1) >> 0) == header->v[0]->edgeflag);
-   assert(((header->edgeflags & 0x2) >> 1) == header->v[1]->edgeflag);
-   assert(((header->edgeflags & 0x4) >> 2) == header->v[2]->edgeflag);
-#endif
-
-   if (header->edgeflags & 0x4) line( stage, v2, v0 );
-   if (header->edgeflags & 0x1) line( stage, v0, v1 );
-   if (header->edgeflags & 0x2) line( stage, v1, v2 );
-}
-
-
-/* Unfilled tri:  
- *
- * Note edgeflags in the vertex struct is not sufficient as we will
- * need to manipulate them when decomposing primitives???
- */
-static void unfilled_tri( struct draw_stage *stage,
-                         struct prim_header *header )
-{
-   struct unfilled_stage *unfilled = unfilled_stage(stage);
-   unsigned mode = unfilled->mode[header->det >= 0.0];
-  
-   switch (mode) {
-   case PIPE_POLYGON_MODE_FILL:
-      stage->next->tri( stage->next, header );
-      break;
-   case PIPE_POLYGON_MODE_LINE:
-      lines( stage, header );
-      break;
-   case PIPE_POLYGON_MODE_POINT:
-      points( stage, header );
-      break;
-   default:
-      assert(0);
-   }   
-}
-
-
-static void unfilled_first_tri( struct draw_stage *stage, 
-                               struct prim_header *header )
-{
-   struct unfilled_stage *unfilled = unfilled_stage(stage);
-
-   unfilled->mode[0] = stage->draw->rasterizer->fill_ccw; /* front */
-   unfilled->mode[1] = stage->draw->rasterizer->fill_cw;  /* back */
-
-   stage->tri = unfilled_tri;
-   stage->tri( stage, header );
-}
-
-
-static void unfilled_line( struct draw_stage *stage,
-                           struct prim_header *header )
-{
-   stage->next->line( stage->next, header );
-}
-
-
-static void unfilled_point( struct draw_stage *stage,
-                            struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void unfilled_flush( struct draw_stage *stage,
-                           unsigned flags )
-{
-   stage->next->flush( stage->next, flags );
-
-   stage->tri = unfilled_first_tri;
-}
-
-
-static void unfilled_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void unfilled_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-/**
- * Create unfilled triangle stage.
- */
-struct draw_stage *draw_unfilled_stage( struct draw_context *draw )
-{
-   struct unfilled_stage *unfilled = CALLOC_STRUCT(unfilled_stage);
-
-   draw_alloc_temp_verts( &unfilled->stage, 0 );
-
-   unfilled->stage.draw = draw;
-   unfilled->stage.next = NULL;
-   unfilled->stage.tmp = NULL;
-   unfilled->stage.point = unfilled_point;
-   unfilled->stage.line = unfilled_line;
-   unfilled->stage.tri = unfilled_first_tri;
-   unfilled->stage.flush = unfilled_flush;
-   unfilled->stage.reset_stipple_counter = unfilled_reset_stipple_counter;
-   unfilled->stage.destroy = unfilled_destroy;
-
-   return &unfilled->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_validate.c b/src/gallium/auxiliary/draw/draw_validate.c
deleted file mode 100644 (file)
index e163e07..0000000
+++ /dev/null
@@ -1,312 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "draw_private.h"
-
-static boolean points( unsigned prim )
-{
-   return (prim == PIPE_PRIM_POINTS);
-}
-
-static boolean lines( unsigned prim )
-{
-   return (prim == PIPE_PRIM_LINES ||
-           prim == PIPE_PRIM_LINE_STRIP ||
-           prim == PIPE_PRIM_LINE_LOOP);
-}
-
-static boolean triangles( unsigned prim )
-{
-   return prim >= PIPE_PRIM_TRIANGLES;
-}
-
-/**
- * Check if we need any special pipeline stages, or whether
- * prims/verts can go through untouched.  Don't test for bypass
- * clipping or vs modes, this function is just about the primitive
- * pipeline stages.
- */
-boolean
-draw_need_pipeline(const struct draw_context *draw, 
-                   unsigned int prim )
-{
-   /* Don't have to worry about triangles turning into lines/points
-    * and triggering the pipeline, because we have to trigger the
-    * pipeline *anyway* if unfilled mode is active.
-    */
-   if (lines(prim)) 
-   {
-      /* line stipple */
-      if (draw->rasterizer->line_stipple_enable && draw->line_stipple)
-         return TRUE;
-
-      /* wide lines */
-      if (draw->rasterizer->line_width > draw->wide_line_threshold)
-         return TRUE;
-
-      /* AA lines */
-      if (draw->rasterizer->line_smooth && draw->pipeline.aaline)
-         return TRUE;
-   }
-
-   if (points(prim))
-   {
-      /* large points */
-      if (draw->rasterizer->point_size > draw->wide_point_threshold)
-         return TRUE;
-
-      /* AA points */
-      if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
-         return TRUE;
-
-      /* point sprites */
-      if (draw->rasterizer->point_sprite && draw->point_sprite)
-         return TRUE;
-   }
-
-
-   if (triangles(prim)) 
-   {
-      /* polygon stipple */
-      if (draw->rasterizer->poly_stipple_enable && draw->pipeline.pstipple)
-         return TRUE;
-
-      /* unfilled polygons */
-      if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
-          draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL)
-         return TRUE;
-      
-      /* polygon offset */
-      if (draw->rasterizer->offset_cw || draw->rasterizer->offset_ccw)
-         return TRUE;
-
-      /* two-side lighting */
-      if (draw->rasterizer->light_twoside)
-         return TRUE;
-   }
-
-   /* polygon cull - this is difficult - hardware can cull just fine
-    * most of the time (though sometimes CULL_NEITHER is unsupported.
-    * 
-    * Generally this isn't a reason to require the pipeline, though.
-    *
-   if (draw->rasterizer->cull_mode)
-      return TRUE;
-    */
-
-   return FALSE;
-}
-
-
-
-/**
- * Rebuild the rendering pipeline.
- */
-static struct draw_stage *validate_pipeline( struct draw_stage *stage )
-{
-   struct draw_context *draw = stage->draw;
-   struct draw_stage *next = draw->pipeline.rasterize;
-   int need_det = 0;
-   int precalc_flat = 0;
-   boolean wide_lines, wide_points;
-
-   /* Set the validate's next stage to the rasterize stage, so that it
-    * can be found later if needed for flushing.
-    */
-   stage->next = next;
-
-   /* drawing wide lines? */
-   wide_lines = (draw->rasterizer->line_width > draw->wide_line_threshold
-                 && !draw->rasterizer->line_smooth);
-
-   /* drawing large points? */
-   if (draw->rasterizer->point_sprite && draw->point_sprite)
-      wide_points = TRUE;
-   else if (draw->rasterizer->point_smooth && draw->pipeline.aapoint)
-      wide_points = FALSE;
-   else if (draw->rasterizer->point_size > draw->wide_point_threshold)
-      wide_points = TRUE;
-   else
-      wide_points = FALSE;
-
-   /*
-    * NOTE: we build up the pipeline in end-to-start order.
-    *
-    * TODO: make the current primitive part of the state and build
-    * shorter pipelines for lines & points.
-    */
-
-   if (draw->rasterizer->line_smooth && draw->pipeline.aaline) {
-      draw->pipeline.aaline->next = next;
-      next = draw->pipeline.aaline;
-   }
-
-   if (draw->rasterizer->point_smooth && draw->pipeline.aapoint) {
-      draw->pipeline.aapoint->next = next;
-      next = draw->pipeline.aapoint;
-   }
-
-   if (wide_lines) {
-      draw->pipeline.wide_line->next = next;
-      next = draw->pipeline.wide_line;
-      precalc_flat = 1;
-   }
-
-   if (wide_points || draw->rasterizer->point_sprite) {
-      draw->pipeline.wide_point->next = next;
-      next = draw->pipeline.wide_point;
-   }
-
-   if (draw->rasterizer->line_stipple_enable && draw->line_stipple) {
-      draw->pipeline.stipple->next = next;
-      next = draw->pipeline.stipple;
-      precalc_flat = 1;                /* only needed for lines really */
-   }
-
-   if (draw->rasterizer->poly_stipple_enable
-       && draw->pipeline.pstipple) {
-      draw->pipeline.pstipple->next = next;
-      next = draw->pipeline.pstipple;
-   }
-
-   if (draw->rasterizer->fill_cw != PIPE_POLYGON_MODE_FILL ||
-       draw->rasterizer->fill_ccw != PIPE_POLYGON_MODE_FILL) {
-      draw->pipeline.unfilled->next = next;
-      next = draw->pipeline.unfilled;
-      precalc_flat = 1;                /* only needed for triangles really */
-      need_det = 1;
-   }
-
-   if (draw->rasterizer->flatshade && precalc_flat) {
-      draw->pipeline.flatshade->next = next;
-      next = draw->pipeline.flatshade;
-   }
-        
-   if (draw->rasterizer->offset_cw ||
-       draw->rasterizer->offset_ccw) {
-      draw->pipeline.offset->next = next;
-      next = draw->pipeline.offset;
-      need_det = 1;
-   }
-
-   if (draw->rasterizer->light_twoside) {
-      draw->pipeline.twoside->next = next;
-      next = draw->pipeline.twoside;
-      need_det = 1;
-   }
-
-   /* Always run the cull stage as we calculate determinant there
-    * also.  
-    *
-    * This can actually be a win as culling out the triangles can lead
-    * to less work emitting vertices, smaller vertex buffers, etc.
-    * It's difficult to say whether this will be true in general.
-    */
-   if (need_det || draw->rasterizer->cull_mode) {
-      draw->pipeline.cull->next = next;
-      next = draw->pipeline.cull;
-   }
-
-   /* Clip stage
-    */
-   if (!draw->rasterizer->bypass_clipping)
-   {
-      draw->pipeline.clip->next = next;
-      next = draw->pipeline.clip;
-   }
-
-   
-   draw->pipeline.first = next;
-   return next;
-}
-
-static void validate_tri( struct draw_stage *stage, 
-                         struct prim_header *header )
-{
-   struct draw_stage *pipeline = validate_pipeline( stage );
-   pipeline->tri( pipeline, header );
-}
-
-static void validate_line( struct draw_stage *stage, 
-                          struct prim_header *header )
-{
-   struct draw_stage *pipeline = validate_pipeline( stage );
-   pipeline->line( pipeline, header );
-}
-
-static void validate_point( struct draw_stage *stage, 
-                           struct prim_header *header )
-{
-   struct draw_stage *pipeline = validate_pipeline( stage );
-   pipeline->point( pipeline, header );
-}
-
-static void validate_reset_stipple_counter( struct draw_stage *stage )
-{
-   struct draw_stage *pipeline = validate_pipeline( stage );
-   pipeline->reset_stipple_counter( pipeline );
-}
-
-static void validate_flush( struct draw_stage *stage, 
-                           unsigned flags )
-{
-   /* May need to pass a backend flush on to the rasterize stage.
-    */
-   if (stage->next)
-      stage->next->flush( stage->next, flags );
-}
-
-
-static void validate_destroy( struct draw_stage *stage )
-{
-   FREE( stage );
-}
-
-
-/**
- * Create validate pipeline stage.
- */
-struct draw_stage *draw_validate_stage( struct draw_context *draw )
-{
-   struct draw_stage *stage = CALLOC_STRUCT(draw_stage);
-
-   stage->draw = draw;
-   stage->next = NULL;
-   stage->point = validate_point;
-   stage->line = validate_line;
-   stage->tri = validate_tri;
-   stage->flush = validate_flush;
-   stage->reset_stipple_counter = validate_reset_stipple_counter;
-   stage->destroy = validate_destroy;
-
-   return stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_vbuf.c b/src/gallium/auxiliary/draw/draw_vbuf.c
deleted file mode 100644 (file)
index 30dceeb..0000000
+++ /dev/null
@@ -1,529 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \file
- * Vertex buffer drawing stage.
- * 
- * \author José Fonseca <jrfonsec@tungstengraphics.com>
- * \author Keith Whitwell <keith@tungstengraphics.com>
- */
-
-
-#include "pipe/p_debug.h"
-#include "pipe/p_util.h"
-
-#include "draw_vbuf.h"
-#include "draw_private.h"
-#include "draw_vertex.h"
-#include "translate/translate.h"
-
-
-/**
- * Vertex buffer emit stage.
- */
-struct vbuf_stage {
-   struct draw_stage stage; /**< This must be first (base class) */
-
-   struct vbuf_render *render;
-   
-   const struct vertex_info *vinfo;
-   
-   /** Vertex size in bytes */
-   unsigned vertex_size;
-
-   struct translate *translate;
-   
-   /* FIXME: we have no guarantee that 'unsigned' is 32bit */
-
-   /** Vertices in hardware format */
-   unsigned *vertices;
-   unsigned *vertex_ptr;
-   unsigned max_vertices;
-   unsigned nr_vertices;
-   
-   /** Indices */
-   ushort *indices;
-   unsigned max_indices;
-   unsigned nr_indices;
-
-   /* Cache point size somewhere it's address won't change:
-    */
-   float point_size;
-};
-
-
-/**
- * Basically a cast wrapper.
- */
-static INLINE struct vbuf_stage *
-vbuf_stage( struct draw_stage *stage )
-{
-   assert(stage);
-   return (struct vbuf_stage *)stage;
-}
-
-
-static void vbuf_flush_indices( struct vbuf_stage *vbuf );
-static void vbuf_flush_vertices( struct vbuf_stage *vbuf );
-static void vbuf_alloc_vertices( struct vbuf_stage *vbuf );
-
-
-static INLINE boolean 
-overflow( void *map, void *ptr, unsigned bytes, unsigned bufsz )
-{
-   unsigned long used = (unsigned long) ((char *)ptr - (char *)map);
-   return (used + bytes) > bufsz;
-}
-
-
-static INLINE void 
-check_space( struct vbuf_stage *vbuf, unsigned nr )
-{
-   if (vbuf->nr_vertices + nr > vbuf->max_vertices ) {
-      vbuf_flush_vertices(vbuf);
-      vbuf_alloc_vertices(vbuf);
-   }
-
-   if (vbuf->nr_indices + nr > vbuf->max_indices )
-      vbuf_flush_indices(vbuf);
-}
-
-
-static INLINE void
-dump_emitted_vertex(const struct vertex_info *vinfo, const uint8_t *data)
-{
-//   assert(vinfo == vbuf->render->get_vertex_info(vbuf->render));
-   unsigned i, j;
-
-   for (i = 0; i < vinfo->num_attribs; i++) {
-      j = vinfo->src_index[i];
-      switch (vinfo->emit[i]) {
-      case EMIT_OMIT:
-         debug_printf("EMIT_OMIT:");
-         break;
-      case EMIT_1F:
-         debug_printf("EMIT_1F:\t");
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         break;
-      case EMIT_1F_PSIZE:
-         debug_printf("EMIT_1F_PSIZE:\t");
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         break;
-      case EMIT_2F:
-         debug_printf("EMIT_2F:\t");
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         break;
-      case EMIT_3F:
-         debug_printf("EMIT_3F:\t");
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         data += sizeof(float);
-         break;
-      case EMIT_4F:
-         debug_printf("EMIT_4F:\t");
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         debug_printf("%f ", *(float *)data); data += sizeof(float);
-         break;
-      case EMIT_4UB:
-         debug_printf("EMIT_4UB:\t");
-         debug_printf("%u ", *data++);
-         debug_printf("%u ", *data++);
-         debug_printf("%u ", *data++);
-         debug_printf("%u ", *data++);
-         break;
-      default:
-         assert(0);
-      }
-      debug_printf("\n");
-   }
-   debug_printf("\n");
-}
-
-
-/**
- * Extract the needed fields from post-transformed vertex and emit
- * a hardware(driver) vertex.
- * Recall that the vertices are constructed by the 'draw' module and
- * have a couple of slots at the beginning (1-dword header, 4-dword
- * clip pos) that we ignore here.  We only use the vertex->data[] fields.
- */
-static INLINE ushort 
-emit_vertex( struct vbuf_stage *vbuf,
-             struct vertex_header *vertex )
-{
-   if(vertex->vertex_id == UNDEFINED_VERTEX_ID) {      
-      /* Hmm - vertices are emitted one at a time - better make sure
-       * set_buffer is efficient.  Consider a special one-shot mode for
-       * translate.
-       */
-      vbuf->translate->set_buffer(vbuf->translate, 0, vertex->data[0], 0);
-      vbuf->translate->run(vbuf->translate, 0, 1, vbuf->vertex_ptr);
-
-      if (0) dump_emitted_vertex(vbuf->vinfo, (uint8_t *)vbuf->vertex_ptr);
-      
-      vbuf->vertex_ptr += vbuf->vertex_size/4;
-      vertex->vertex_id = vbuf->nr_vertices++;
-   }
-
-   return vertex->vertex_id;
-}
-
-
-static void 
-vbuf_tri( struct draw_stage *stage,
-          struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-   unsigned i;
-
-   check_space( vbuf, 3 );
-
-   for (i = 0; i < 3; i++) {
-      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
-   }
-}
-
-
-static void 
-vbuf_line( struct draw_stage *stage, 
-           struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-   unsigned i;
-
-   check_space( vbuf, 2 );
-
-   for (i = 0; i < 2; i++) {
-      vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[i] );
-   }   
-}
-
-
-static void 
-vbuf_point( struct draw_stage *stage, 
-            struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   check_space( vbuf, 1 );
-
-   vbuf->indices[vbuf->nr_indices++] = emit_vertex( vbuf, prim->v[0] );
-}
-
-
-
-
-/**
- * Set the prim type for subsequent vertices.
- * This may result in a new vertex size.  The existing vbuffer (if any)
- * will be flushed if needed and a new one allocated.
- */
-static void
-vbuf_set_prim( struct vbuf_stage *vbuf, uint prim )
-{
-   struct translate_key hw_key;
-   unsigned dst_offset;
-   unsigned i;
-
-   vbuf->render->set_primitive(vbuf->render, prim);
-
-   /* Must do this after set_primitive() above:
-    * 
-    * XXX: need some state managment to track when this needs to be
-    * recalculated.  The driver should tell us whether there was a
-    * state change.
-    */
-   vbuf->vinfo = vbuf->render->get_vertex_info(vbuf->render);
-
-   if (vbuf->vertex_size != vbuf->vinfo->size * sizeof(float)) {
-      vbuf_flush_vertices(vbuf);
-      vbuf->vertex_size = vbuf->vinfo->size * sizeof(float);
-   }
-
-   /* Translate from pipeline vertices to hw vertices.
-    */
-   dst_offset = 0;
-   memset(&hw_key, 0, sizeof(hw_key));
-
-   for (i = 0; i < vbuf->vinfo->num_attribs; i++) {
-      unsigned emit_sz = 0;
-      unsigned src_buffer = 0;
-      unsigned output_format;
-      unsigned src_offset = (vbuf->vinfo->src_index[i] * 4 * sizeof(float) );
-
-      switch (vbuf->vinfo->emit[i]) {
-      case EMIT_4F:
-        output_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-        emit_sz = 4 * sizeof(float);
-        break;
-      case EMIT_3F:
-        output_format = PIPE_FORMAT_R32G32B32_FLOAT;
-        emit_sz = 3 * sizeof(float);
-        break;
-      case EMIT_2F:
-        output_format = PIPE_FORMAT_R32G32_FLOAT;
-        emit_sz = 2 * sizeof(float);
-        break;
-      case EMIT_1F:
-        output_format = PIPE_FORMAT_R32_FLOAT;
-        emit_sz = 1 * sizeof(float);
-        break;
-      case EMIT_1F_PSIZE:
-        output_format = PIPE_FORMAT_R32_FLOAT;
-        emit_sz = 1 * sizeof(float);
-        src_buffer = 1;
-        src_offset = 0;
-        break;
-      case EMIT_4UB:
-        output_format = PIPE_FORMAT_B8G8R8A8_UNORM;
-        emit_sz = 4 * sizeof(ubyte);
-      default:
-        assert(0);
-        output_format = PIPE_FORMAT_NONE;
-        emit_sz = 0;
-        break;
-      }
-      
-      hw_key.element[i].input_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
-      hw_key.element[i].input_buffer = src_buffer;
-      hw_key.element[i].input_offset = src_offset;
-      hw_key.element[i].output_format = output_format;
-      hw_key.element[i].output_offset = dst_offset;
-
-      dst_offset += emit_sz;
-   }
-
-   hw_key.nr_elements = vbuf->vinfo->num_attribs;
-   hw_key.output_stride = vbuf->vinfo->size * 4;
-
-   /* Don't bother with caching at this stage:
-    */
-   if (!vbuf->translate ||
-       memcmp(&vbuf->translate->key, &hw_key, sizeof(hw_key)) != 0) 
-   {
-      if (vbuf->translate)
-        vbuf->translate->release(vbuf->translate);
-
-      vbuf->translate = translate_create( &hw_key );
-
-      vbuf->translate->set_buffer(vbuf->translate, 1, &vbuf->point_size, 0);
-   }
-
-   vbuf->point_size = vbuf->stage.draw->rasterizer->point_size;
-
-   /* Allocate new buffer?
-    */
-   if (!vbuf->vertices)
-      vbuf_alloc_vertices(vbuf);
-}
-
-
-static void 
-vbuf_first_tri( struct draw_stage *stage,
-                struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   vbuf_flush_indices( vbuf );   
-   stage->tri = vbuf_tri;
-   vbuf_set_prim(vbuf, PIPE_PRIM_TRIANGLES);
-   stage->tri( stage, prim );
-}
-
-
-static void 
-vbuf_first_line( struct draw_stage *stage,
-                 struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   vbuf_flush_indices( vbuf );
-   stage->line = vbuf_line;
-   vbuf_set_prim(vbuf, PIPE_PRIM_LINES);
-   stage->line( stage, prim );
-}
-
-
-static void 
-vbuf_first_point( struct draw_stage *stage,
-                  struct prim_header *prim )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   vbuf_flush_indices( vbuf );
-   stage->point = vbuf_point;
-   vbuf_set_prim(vbuf, PIPE_PRIM_POINTS);
-   stage->point( stage, prim );
-}
-
-
-static void 
-vbuf_flush_indices( struct vbuf_stage *vbuf ) 
-{
-   if(!vbuf->nr_indices)
-      return;
-   
-   assert((uint) (vbuf->vertex_ptr - vbuf->vertices) == 
-          vbuf->nr_vertices * vbuf->vertex_size / sizeof(unsigned));
-
-   vbuf->render->draw(vbuf->render, vbuf->indices, vbuf->nr_indices);
-   
-   vbuf->nr_indices = 0;
-}
-
-
-/**
- * Flush existing vertex buffer and allocate a new one.
- * 
- * XXX: We separate flush-on-index-full and flush-on-vb-full, but may 
- * raise issues uploading vertices if the hardware wants to flush when
- * we flush.
- */
-static void 
-vbuf_flush_vertices( struct vbuf_stage *vbuf )
-{
-   if(vbuf->vertices) {      
-      vbuf_flush_indices(vbuf);
-      
-      /* Reset temporary vertices ids */
-      if(vbuf->nr_vertices)
-        draw_reset_vertex_ids( vbuf->stage.draw );
-      
-      /* Free the vertex buffer */
-      vbuf->render->release_vertices(vbuf->render,
-                                     vbuf->vertices,
-                                     vbuf->vertex_size,
-                                     vbuf->nr_vertices);
-      vbuf->max_vertices = vbuf->nr_vertices = 0;
-      vbuf->vertex_ptr = vbuf->vertices = NULL;
-      
-   }
-}
-   
-
-static void 
-vbuf_alloc_vertices( struct vbuf_stage *vbuf )
-{
-   assert(!vbuf->nr_indices);
-   assert(!vbuf->vertices);
-   
-   /* Allocate a new vertex buffer */
-   vbuf->max_vertices = vbuf->render->max_vertex_buffer_bytes / vbuf->vertex_size;
-   vbuf->vertices = (uint *) vbuf->render->allocate_vertices(vbuf->render,
-                                                            (ushort) vbuf->vertex_size,
-                                                            (ushort) vbuf->max_vertices);
-   vbuf->vertex_ptr = vbuf->vertices;
-}
-
-
-
-static void 
-vbuf_flush( struct draw_stage *stage, unsigned flags )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   vbuf_flush_indices( vbuf );
-
-   stage->point = vbuf_first_point;
-   stage->line = vbuf_first_line;
-   stage->tri = vbuf_first_tri;
-
-   if (flags & DRAW_FLUSH_BACKEND)
-      vbuf_flush_vertices( vbuf );
-}
-
-
-static void 
-vbuf_reset_stipple_counter( struct draw_stage *stage )
-{
-   /* XXX: Need to do something here for hardware with linestipple.
-    */
-   (void) stage;
-}
-
-
-static void vbuf_destroy( struct draw_stage *stage )
-{
-   struct vbuf_stage *vbuf = vbuf_stage( stage );
-
-   if(vbuf->indices)
-      align_free( vbuf->indices );
-   
-   if(vbuf->translate)
-      vbuf->translate->release( vbuf->translate );
-
-   if (vbuf->render)
-      vbuf->render->destroy( vbuf->render );
-
-   FREE( stage );
-}
-
-
-/**
- * Create a new primitive vbuf/render stage.
- */
-struct draw_stage *draw_vbuf_stage( struct draw_context *draw,
-                                    struct vbuf_render *render )
-{
-   struct vbuf_stage *vbuf = CALLOC_STRUCT(vbuf_stage);
-
-   if(!vbuf)
-      goto fail;
-   
-   vbuf->stage.draw = draw;
-   vbuf->stage.point = vbuf_first_point;
-   vbuf->stage.line = vbuf_first_line;
-   vbuf->stage.tri = vbuf_first_tri;
-   vbuf->stage.flush = vbuf_flush;
-   vbuf->stage.reset_stipple_counter = vbuf_reset_stipple_counter;
-   vbuf->stage.destroy = vbuf_destroy;
-   
-   vbuf->render = render;
-   vbuf->max_indices = MAX2(render->max_indices, UNDEFINED_VERTEX_ID-1);
-
-   vbuf->indices = (ushort *) align_malloc( vbuf->max_indices * 
-                                           sizeof(vbuf->indices[0]), 
-                                           16 );
-   if(!vbuf->indices)
-      goto fail;
-   
-   vbuf->vertices = NULL;
-   vbuf->vertex_ptr = vbuf->vertices;
-   
-   return &vbuf->stage;
-
- fail:
-   if (vbuf)
-      vbuf_destroy(&vbuf->stage);
-   
-   return NULL;
-}
diff --git a/src/gallium/auxiliary/draw/draw_wide_line.c b/src/gallium/auxiliary/draw/draw_wide_line.c
deleted file mode 100644 (file)
index 9a168ce..0000000
+++ /dev/null
@@ -1,190 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_private.h"
-
-
-struct wideline_stage {
-   struct draw_stage stage;
-
-   float half_line_width;
-};
-
-
-
-static INLINE struct wideline_stage *wideline_stage( struct draw_stage *stage )
-{
-   return (struct wideline_stage *)stage;
-}
-
-
-static void wideline_point( struct draw_stage *stage,
-                               struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-
-static void wideline_tri( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-/**
- * Draw a wide line by drawing a quad (two triangles).
- * XXX need to disable polygon stipple.
- */
-static void wideline_line( struct draw_stage *stage,
-                           struct prim_header *header )
-{
-   /*const struct wideline_stage *wide = wideline_stage(stage);*/
-   const float half_width = 0.5f * stage->draw->rasterizer->line_width;
-
-   struct prim_header tri;
-
-   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
-   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
-   struct vertex_header *v2 = dup_vert(stage, header->v[1], 2);
-   struct vertex_header *v3 = dup_vert(stage, header->v[1], 3);
-
-   float *pos0 = v0->data[0];
-   float *pos1 = v1->data[0];
-   float *pos2 = v2->data[0];
-   float *pos3 = v3->data[0];
-
-   const float dx = FABSF(pos0[0] - pos2[0]);
-   const float dy = FABSF(pos0[1] - pos2[1]);
-
-   /* small tweak to meet GL specification */
-   const float bias = 0.125f;
-
-   /*
-    * Draw wide line as a quad (two tris) by "stretching" the line along
-    * X or Y.
-    * We need to tweak coords in several ways to be conformant here.
-    */
-
-   if (dx > dy) {
-      /* x-major line */
-      pos0[1] = pos0[1] - half_width - bias;
-      pos1[1] = pos1[1] + half_width - bias;
-      pos2[1] = pos2[1] - half_width - bias;
-      pos3[1] = pos3[1] + half_width - bias;
-      if (pos0[0] < pos2[0]) {
-         /* left to right line */
-         pos0[0] -= 0.5f;
-         pos1[0] -= 0.5f;
-         pos2[0] -= 0.5f;
-         pos3[0] -= 0.5f;
-      }
-      else {
-         /* right to left line */
-         pos0[0] += 0.5f;
-         pos1[0] += 0.5f;
-         pos2[0] += 0.5f;
-         pos3[0] += 0.5f;
-      }
-   }
-   else {
-      /* y-major line */
-      pos0[0] = pos0[0] - half_width + bias;
-      pos1[0] = pos1[0] + half_width + bias;
-      pos2[0] = pos2[0] - half_width + bias;
-      pos3[0] = pos3[0] + half_width + bias;
-      if (pos0[1] < pos2[1]) {
-         /* top to bottom line */
-         pos0[1] -= 0.5f;
-         pos1[1] -= 0.5f;
-         pos2[1] -= 0.5f;
-         pos3[1] -= 0.5f;
-      }
-      else {
-         /* bottom to top line */
-         pos0[1] += 0.5f;
-         pos1[1] += 0.5f;
-         pos2[1] += 0.5f;
-         pos3[1] += 0.5f;
-      }
-   }
-
-   tri.det = header->det;  /* only the sign matters */
-   tri.v[0] = v0;
-   tri.v[1] = v2;
-   tri.v[2] = v3;
-   stage->next->tri( stage->next, &tri );
-
-   tri.v[0] = v0;
-   tri.v[1] = v3;
-   tri.v[2] = v1;
-   stage->next->tri( stage->next, &tri );
-}
-
-
-static void wideline_flush( struct draw_stage *stage, unsigned flags )
-{
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void wideline_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void wideline_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-struct draw_stage *draw_wide_line_stage( struct draw_context *draw )
-{
-   struct wideline_stage *wide = CALLOC_STRUCT(wideline_stage);
-
-   draw_alloc_temp_verts( &wide->stage, 4 );
-
-   wide->stage.draw = draw;
-   wide->stage.next = NULL;
-   wide->stage.point = wideline_point;
-   wide->stage.line = wideline_line;
-   wide->stage.tri = wideline_tri;
-   wide->stage.flush = wideline_flush;
-   wide->stage.reset_stipple_counter = wideline_reset_stipple_counter;
-   wide->stage.destroy = wideline_destroy;
-
-   return &wide->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_wide_point.c b/src/gallium/auxiliary/draw/draw_wide_point.c
deleted file mode 100644 (file)
index 3d0add0..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_vs.h"
-
-
-struct widepoint_stage {
-   struct draw_stage stage;
-
-   float half_point_size;
-   float point_size_min;
-   float point_size_max;
-
-   float xbias;
-   float ybias;
-
-   uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
-   uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
-   uint num_texcoords;
-
-   int psize_slot;
-};
-
-
-
-static INLINE struct widepoint_stage *
-widepoint_stage( struct draw_stage *stage )
-{
-   return (struct widepoint_stage *)stage;
-}
-
-
-static void passthrough_point( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-static void widepoint_line( struct draw_stage *stage,
-                            struct prim_header *header )
-{
-   stage->next->line(stage->next, header);
-}
-
-static void widepoint_tri( struct draw_stage *stage,
-                           struct prim_header *header )
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-/**
- * Set the vertex texcoords for sprite mode.
- * Coords may be left untouched or set to a right-side-up or upside-down
- * orientation.
- */
-static void set_texcoords(const struct widepoint_stage *wide,
-                          struct vertex_header *v, const float tc[4])
-{
-   uint i;
-   for (i = 0; i < wide->num_texcoords; i++) {
-      if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
-         uint j = wide->texcoord_slot[i];
-         v->data[j][0] = tc[0];
-         if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
-            v->data[j][1] = 1.0f - tc[1];
-         else
-            v->data[j][1] = tc[1];
-         v->data[j][2] = tc[2];
-         v->data[j][3] = tc[3];
-      }
-   }
-}
-
-
-/* If there are lots of sprite points (and why wouldn't there be?) it
- * would probably be more sensible to change hardware setup to
- * optimize this rather than doing the whole thing in software like
- * this.
- */
-static void widepoint_point( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   const struct widepoint_stage *wide = widepoint_stage(stage);
-   const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
-   float half_size;
-   float left_adj, right_adj, bot_adj, top_adj;
-
-   struct prim_header tri;
-
-   /* four dups of original vertex */
-   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
-   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
-   struct vertex_header *v2 = dup_vert(stage, header->v[0], 2);
-   struct vertex_header *v3 = dup_vert(stage, header->v[0], 3);
-
-   float *pos0 = v0->data[0];
-   float *pos1 = v1->data[0];
-   float *pos2 = v2->data[0];
-   float *pos3 = v3->data[0];
-
-   /* point size is either per-vertex or fixed size */
-   if (wide->psize_slot >= 0) {
-      half_size = header->v[0]->data[wide->psize_slot][0];
-
-      /* XXX: temporary -- do this in the vertex shader??
-       */
-      half_size = CLAMP(half_size,
-                        wide->point_size_min,
-                        wide->point_size_max);
-      
-      half_size *= 0.5f; 
-   }
-   else {
-      half_size = wide->half_point_size;
-   }
-
-   left_adj = -half_size + wide->xbias;
-   right_adj = half_size + wide->xbias;
-   bot_adj = half_size + wide->ybias;
-   top_adj = -half_size + wide->ybias;
-
-   pos0[0] += left_adj;
-   pos0[1] += top_adj;
-
-   pos1[0] += left_adj;
-   pos1[1] += bot_adj;
-
-   pos2[0] += right_adj;
-   pos2[1] += top_adj;
-
-   pos3[0] += right_adj;
-   pos3[1] += bot_adj;
-
-   if (sprite) {
-      static const float tex00[4] = { 0, 0, 0, 1 };
-      static const float tex01[4] = { 0, 1, 0, 1 };
-      static const float tex11[4] = { 1, 1, 0, 1 };
-      static const float tex10[4] = { 1, 0, 0, 1 };
-      set_texcoords( wide, v0, tex00 );
-      set_texcoords( wide, v1, tex01 );
-      set_texcoords( wide, v2, tex10 );
-      set_texcoords( wide, v3, tex11 );
-   }
-
-   tri.det = header->det;  /* only the sign matters */
-   tri.v[0] = v0;
-   tri.v[1] = v2;
-   tri.v[2] = v3;
-   stage->next->tri( stage->next, &tri );
-
-   tri.v[0] = v0;
-   tri.v[1] = v3;
-   tri.v[2] = v1;
-   stage->next->tri( stage->next, &tri );
-}
-
-
-static void widepoint_first_point( struct draw_stage *stage, 
-                             struct prim_header *header )
-{
-   struct widepoint_stage *wide = widepoint_stage(stage);
-   struct draw_context *draw = stage->draw;
-
-   wide->half_point_size = 0.5f * draw->rasterizer->point_size;
-   wide->point_size_min = draw->rasterizer->point_size_min;
-   wide->point_size_max = draw->rasterizer->point_size_max;
-   wide->xbias = 0.0;
-   wide->ybias = 0.0;
-
-   if (draw->rasterizer->gl_rasterization_rules) {
-      wide->xbias = 0.125;
-   }
-
-   /* XXX we won't know the real size if it's computed by the vertex shader! */
-   if ((draw->rasterizer->point_size > draw->wide_point_threshold) ||
-       (draw->rasterizer->point_sprite && draw->point_sprite)) {
-      stage->point = widepoint_point;
-   }
-   else {
-      stage->point = passthrough_point;
-   }
-
-   if (draw->rasterizer->point_sprite) {
-      /* find vertex shader texcoord outputs */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
-      uint i, j = 0;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
-            wide->texcoord_slot[j] = i;
-            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
-            j++;
-         }
-      }
-      wide->num_texcoords = j;
-   }
-
-   wide->psize_slot = -1;
-   if (draw->rasterizer->point_size_per_vertex) {
-      /* find PSIZ vertex output */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
-      uint i;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
-            wide->psize_slot = i;
-            break;
-         }
-      }
-   }
-   
-   stage->point( stage, header );
-}
-
-
-static void widepoint_flush( struct draw_stage *stage, unsigned flags )
-{
-   stage->point = widepoint_first_point;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void widepoint_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void widepoint_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-struct draw_stage *draw_wide_point_stage( struct draw_context *draw )
-{
-   struct widepoint_stage *wide = CALLOC_STRUCT(widepoint_stage);
-
-   draw_alloc_temp_verts( &wide->stage, 4 );
-
-   wide->stage.draw = draw;
-   wide->stage.next = NULL;
-   wide->stage.point = widepoint_first_point;
-   wide->stage.line = widepoint_line;
-   wide->stage.tri = widepoint_tri;
-   wide->stage.flush = widepoint_flush;
-   wide->stage.reset_stipple_counter = widepoint_reset_stipple_counter;
-   wide->stage.destroy = widepoint_destroy;
-
-   return &wide->stage;
-}
diff --git a/src/gallium/auxiliary/draw/draw_wide_prims.c b/src/gallium/auxiliary/draw/draw_wide_prims.c
deleted file mode 100644 (file)
index d6bff11..0000000
+++ /dev/null
@@ -1,366 +0,0 @@
-/**************************************************************************
- * 
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- * 
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * 
- **************************************************************************/
-
-/* Authors:  Keith Whitwell <keith@tungstengraphics.com>
- */
-
-#include "pipe/p_util.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_shader_tokens.h"
-#include "draw_private.h"
-
-
-struct wide_stage {
-   struct draw_stage stage;
-
-   float half_line_width;
-   float half_point_size;
-
-   uint texcoord_slot[PIPE_MAX_SHADER_OUTPUTS];
-   uint texcoord_mode[PIPE_MAX_SHADER_OUTPUTS];
-   uint num_texcoords;
-
-   int psize_slot;
-};
-
-
-
-static INLINE struct wide_stage *wide_stage( struct draw_stage *stage )
-{
-   return (struct wide_stage *)stage;
-}
-
-
-static void passthrough_point( struct draw_stage *stage,
-                               struct prim_header *header )
-{
-   stage->next->point( stage->next, header );
-}
-
-static void passthrough_line( struct draw_stage *stage,
-                              struct prim_header *header )
-{
-   stage->next->line(stage->next, header);
-}
-
-static void passthrough_tri( struct draw_stage *stage,
-                             struct prim_header *header )
-{
-   stage->next->tri(stage->next, header);
-}
-
-
-/**
- * Draw a wide line by drawing a quad (two triangles).
- * XXX need to disable polygon stipple.
- */
-static void wide_line( struct draw_stage *stage,
-                      struct prim_header *header )
-{
-   const struct wide_stage *wide = wide_stage(stage);
-   const float half_width = wide->half_line_width;
-
-   struct prim_header tri;
-
-   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
-   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
-   struct vertex_header *v2 = dup_vert(stage, header->v[1], 2);
-   struct vertex_header *v3 = dup_vert(stage, header->v[1], 3);
-
-   float *pos0 = v0->data[0];
-   float *pos1 = v1->data[0];
-   float *pos2 = v2->data[0];
-   float *pos3 = v3->data[0];
-
-   const float dx = FABSF(pos0[0] - pos2[0]);
-   const float dy = FABSF(pos0[1] - pos2[1]);
-   
-   /*
-    * Draw wide line as a quad (two tris) by "stretching" the line along
-    * X or Y.
-    * We need to tweak coords in several ways to be conformant here.
-    */
-
-   if (dx > dy) {
-      /* x-major line */
-      pos0[1] = pos0[1] - half_width - 0.25f;
-      pos1[1] = pos1[1] + half_width - 0.25f;
-      pos2[1] = pos2[1] - half_width - 0.25f;
-      pos3[1] = pos3[1] + half_width - 0.25f;
-      if (pos0[0] < pos2[0]) {
-         /* left to right line */
-         pos0[0] -= 0.5f;
-         pos1[0] -= 0.5f;
-         pos2[0] -= 0.5f;
-         pos3[0] -= 0.5f;
-      }
-      else {
-         /* right to left line */
-         pos0[0] += 0.5f;
-         pos1[0] += 0.5f;
-         pos2[0] += 0.5f;
-         pos3[0] += 0.5f;
-      }
-   }
-   else {
-      /* y-major line */
-      pos0[0] = pos0[0] - half_width + 0.25f;
-      pos1[0] = pos1[0] + half_width + 0.25f;
-      pos2[0] = pos2[0] - half_width + 0.25f;
-      pos3[0] = pos3[0] + half_width + 0.25f;
-      if (pos0[1] < pos2[1]) {
-         /* top to bottom line */
-         pos0[1] -= 0.5f;
-         pos1[1] -= 0.5f;
-         pos2[1] -= 0.5f;
-         pos3[1] -= 0.5f;
-      }
-      else {
-         /* bottom to top line */
-         pos0[1] += 0.5f;
-         pos1[1] += 0.5f;
-         pos2[1] += 0.5f;
-         pos3[1] += 0.5f;
-      }
-   }
-
-   tri.det = header->det;  /* only the sign matters */
-   tri.v[0] = v0;
-   tri.v[1] = v2;
-   tri.v[2] = v3;
-   stage->next->tri( stage->next, &tri );
-
-   tri.v[0] = v0;
-   tri.v[1] = v3;
-   tri.v[2] = v1;
-   stage->next->tri( stage->next, &tri );
-}
-
-
-/**
- * Set the vertex texcoords for sprite mode.
- * Coords may be left untouched or set to a right-side-up or upside-down
- * orientation.
- */
-static void set_texcoords(const struct wide_stage *wide,
-                          struct vertex_header *v, const float tc[4])
-{
-   uint i;
-   for (i = 0; i < wide->num_texcoords; i++) {
-      if (wide->texcoord_mode[i] != PIPE_SPRITE_COORD_NONE) {
-         uint j = wide->texcoord_slot[i];
-         v->data[j][0] = tc[0];
-         if (wide->texcoord_mode[i] == PIPE_SPRITE_COORD_LOWER_LEFT)
-            v->data[j][1] = 1.0f - tc[1];
-         else
-            v->data[j][1] = tc[1];
-         v->data[j][2] = tc[2];
-         v->data[j][3] = tc[3];
-      }
-   }
-}
-
-
-/* If there are lots of sprite points (and why wouldn't there be?) it
- * would probably be more sensible to change hardware setup to
- * optimize this rather than doing the whole thing in software like
- * this.
- */
-static void wide_point( struct draw_stage *stage,
-                       struct prim_header *header )
-{
-   const struct wide_stage *wide = wide_stage(stage);
-   const boolean sprite = (boolean) stage->draw->rasterizer->point_sprite;
-   float half_size;
-   float left_adj, right_adj;
-
-   struct prim_header tri;
-
-   /* four dups of original vertex */
-   struct vertex_header *v0 = dup_vert(stage, header->v[0], 0);
-   struct vertex_header *v1 = dup_vert(stage, header->v[0], 1);
-   struct vertex_header *v2 = dup_vert(stage, header->v[0], 2);
-   struct vertex_header *v3 = dup_vert(stage, header->v[0], 3);
-
-   float *pos0 = v0->data[0];
-   float *pos1 = v1->data[0];
-   float *pos2 = v2->data[0];
-   float *pos3 = v3->data[0];
-
-   /* point size is either per-vertex or fixed size */
-   if (wide->psize_slot >= 0) {
-      half_size = 0.5f * header->v[0]->data[wide->psize_slot][0];
-   }
-   else {
-      half_size = wide->half_point_size;
-   }
-
-   left_adj = -half_size; /* + 0.25f;*/
-   right_adj = half_size; /* + 0.25f;*/
-
-   pos0[0] += left_adj;
-   pos0[1] -= half_size;
-
-   pos1[0] += left_adj;
-   pos1[1] += half_size;
-
-   pos2[0] += right_adj;
-   pos2[1] -= half_size;
-
-   pos3[0] += right_adj;
-   pos3[1] += half_size;
-
-   if (sprite) {
-      static const float tex00[4] = { 0, 0, 0, 1 };
-      static const float tex01[4] = { 0, 1, 0, 1 };
-      static const float tex11[4] = { 1, 1, 0, 1 };
-      static const float tex10[4] = { 1, 0, 0, 1 };
-      set_texcoords( wide, v0, tex00 );
-      set_texcoords( wide, v1, tex01 );
-      set_texcoords( wide, v2, tex10 );
-      set_texcoords( wide, v3, tex11 );
-   }
-
-   tri.det = header->det;  /* only the sign matters */
-   tri.v[0] = v0;
-   tri.v[1] = v2;
-   tri.v[2] = v3;
-   stage->next->tri( stage->next, &tri );
-
-   tri.v[0] = v0;
-   tri.v[1] = v3;
-   tri.v[2] = v1;
-   stage->next->tri( stage->next, &tri );
-}
-
-
-static void wide_first_point( struct draw_stage *stage, 
-                             struct prim_header *header )
-{
-   struct wide_stage *wide = wide_stage(stage);
-   struct draw_context *draw = stage->draw;
-
-   wide->half_point_size = 0.5f * draw->rasterizer->point_size;
-
-   /* XXX we won't know the real size if it's computed by the vertex shader! */
-   if (draw->rasterizer->point_size > draw->wide_point_threshold) {
-      stage->point = wide_point;
-   }
-   else {
-      stage->point = passthrough_point;
-   }
-
-   if (draw->rasterizer->point_sprite) {
-      /* find vertex shader texcoord outputs */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
-      uint i, j = 0;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_GENERIC) {
-            wide->texcoord_slot[j] = i;
-            wide->texcoord_mode[j] = draw->rasterizer->sprite_coord_mode[j];
-            j++;
-         }
-      }
-      wide->num_texcoords = j;
-   }
-
-   wide->psize_slot = -1;
-
-   if (draw->rasterizer->point_size_per_vertex) {
-      /* find PSIZ vertex output */
-      const struct draw_vertex_shader *vs = draw->vertex_shader;
-      uint i;
-      for (i = 0; i < vs->info.num_outputs; i++) {
-         if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
-            wide->psize_slot = i;
-            break;
-         }
-      }
-   }
-   
-   stage->point( stage, header );
-}
-
-
-
-static void wide_first_line( struct draw_stage *stage,
-                            struct prim_header *header )
-{
-   struct wide_stage *wide = wide_stage(stage);
-   struct draw_context *draw = stage->draw;
-
-   wide->half_line_width = 0.5f * draw->rasterizer->line_width;
-
-   if (draw->rasterizer->line_width != 1.0) {
-      wide->stage.line = wide_line;
-   }
-   else {
-      wide->stage.line = passthrough_line;
-   }
-   
-   stage->line( stage, header );
-}
-
-
-static void wide_flush( struct draw_stage *stage, unsigned flags )
-{
-   stage->line = wide_first_line;
-   stage->point = wide_first_point;
-   stage->next->flush( stage->next, flags );
-}
-
-
-static void wide_reset_stipple_counter( struct draw_stage *stage )
-{
-   stage->next->reset_stipple_counter( stage->next );
-}
-
-
-static void wide_destroy( struct draw_stage *stage )
-{
-   draw_free_temp_verts( stage );
-   FREE( stage );
-}
-
-
-struct draw_stage *draw_wide_stage( struct draw_context *draw )
-{
-   struct wide_stage *wide = CALLOC_STRUCT(wide_stage);
-
-   draw_alloc_temp_verts( &wide->stage, 4 );
-
-   wide->stage.draw = draw;
-   wide->stage.next = NULL;
-   wide->stage.point = wide_first_point;
-   wide->stage.line = wide_first_line;
-   wide->stage.tri = passthrough_tri;
-   wide->stage.flush = wide_flush;
-   wide->stage.reset_stipple_counter = wide_reset_stipple_counter;
-   wide->stage.destroy = wide_destroy;
-
-   return &wide->stage;
-}