1aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**************************************************************************
2aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
3aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * All Rights Reserved.
5aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
6aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Permission is hereby granted, free of charge, to any person obtaining a
7aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * copy of this software and associated documentation files (the
8aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * "Software"), to deal in the Software without restriction, including
9aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * without limitation the rights to use, copy, modify, merge, publish,
10aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * distribute, sub license, and/or sell copies of the Software, and to
11aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * permit persons to whom the Software is furnished to do so, subject to
12aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * the following conditions:
13aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
14aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * The above copyright notice and this permission notice (including the
15aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * next paragraph) shall be included in all copies or substantial portions
16aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * of the Software.
17aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
18aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
26aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian **************************************************************************/
27aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
28aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
29aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * AA line stage:  AA lines are converted to texture mapped triangles.
30aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian *
31aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Authors:  Brian Paul
32aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
33aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
34aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
35aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#include "pipe/p_context.h"
36aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#include "pipe/p_defines.h"
37aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#include "pipe/p_shader_tokens.h"
3828486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
396df42d80234d13676fc3207cf44f0e371e3372b5Michal Krol
406df42d80234d13676fc3207cf44f0e371e3372b5Michal Krol#include "util/u_format.h"
414f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
424f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
43f6106566081978f663cf08e54bb8908cb58a5316Michal Krol#include "util/u_sampler.h"
44aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
45c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_transform.h"
46c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_dump.h"
47aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
48aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#include "draw_context.h"
49aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#include "draw_private.h"
50507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
51aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
52aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
536f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul/** Approx number of new tokens for instructions in aa_transform_inst() */
546f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul#define NUM_NEW_TOKENS 50
556f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul
566f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul
57aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
5807eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca * Size for the alpha texture used for antialiasing
5907eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca */
6007eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca#define TEXTURE_SIZE_LOG2  5   /* 32 x 32 */
6107eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca
6207eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca/**
63aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Max texture level for the alpha texture used for antialiasing
6407eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca *
6507eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca * Don't use the 1x1 and 2x2 mipmap levels.
66aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
6707eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca#define MAX_TEXTURE_LEVEL  (TEXTURE_SIZE_LOG2 - 2)
68aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
69aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
70aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
71aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Subclass of pipe_shader_state to carry extra fragment shader info.
72aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
73aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstruct aaline_fragment_shader
74aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
75aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct pipe_shader_state state;
76aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void *driver_fs;
77aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void *aaline_fs;
786579440ea98e61871fe781c1c9c681645ddcc075Brian   uint sampler_unit;
798cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul   int generic_attrib;  /**< texcoord/generic used for texture */
80aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian};
81aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
82aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
83aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
84aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Subclass of draw_stage
85aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
86aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstruct aaline_stage
87aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
88aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct draw_stage stage;
89aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
90aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   float half_line_width;
91aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
92aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /** For AA lines, this is the vertex attrib slot for the new texcoords */
93aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   uint tex_slot;
942161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   /** position, not necessarily output zero */
952161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   uint pos_slot;
96aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
97aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void *sampler_cso;
98287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *texture;
99f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   struct pipe_sampler_view *sampler_view;
1004528287e040415c2071012d02f20979ff995c754Keith Whitwell   uint num_samplers;
101f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   uint num_sampler_views;
102aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
103aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
104aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /*
105aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    * Currently bound state
106aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
107aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_fragment_shader *fs;
108aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct {
109aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      void *sampler[PIPE_MAX_SAMPLERS];
110f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      struct pipe_sampler_view *sampler_views[PIPE_MAX_SAMPLERS];
111aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   } state;
112aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
113aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /*
114aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    * Driver interface/override functions
115aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
116aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void * (*driver_create_fs_state)(struct pipe_context *,
117aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian                                    const struct pipe_shader_state *);
118aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void (*driver_bind_fs_state)(struct pipe_context *, void *);
119aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   void (*driver_delete_fs_state)(struct pipe_context *, void *);
120aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
1214528287e040415c2071012d02f20979ff995c754Keith Whitwell   void (*driver_bind_sampler_states)(struct pipe_context *, unsigned,
1224528287e040415c2071012d02f20979ff995c754Keith Whitwell                                      void **);
1238f3bdeaad610d7d5a5c6e73e1e9c721219595754Brian Paul
124f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   void (*driver_set_sampler_views)(struct pipe_context *,
125f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                    unsigned,
126f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                    struct pipe_sampler_view **);
127aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian};
128aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
129aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
130aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
131aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
132aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Subclass of tgsi_transform_context, used for transforming the
133aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * user's fragment shader to add the special AA instructions.
134aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
135aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstruct aa_transform_context {
136aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct tgsi_transform_context base;
137aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   uint tempsUsed;  /**< bitmask */
138aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   int colorOutput; /**< which output is the primary color */
1396579440ea98e61871fe781c1c9c681645ddcc075Brian   uint samplersUsed;  /**< bitfield of samplers used */
1406579440ea98e61871fe781c1c9c681645ddcc075Brian   int freeSampler;  /** an available sampler for the pstipple */
141aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   int maxInput, maxGeneric;  /**< max input index found */
142aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   int colorTemp, texTemp;  /**< temp registers */
143aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   boolean firstInstruction;
144aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian};
145aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
146aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
147aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
148aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * TGSI declaration transform callback.
149aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Look for a free sampler, a free input attrib, and two free temp regs.
150aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
151aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
152aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaa_transform_decl(struct tgsi_transform_context *ctx,
153aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian                  struct tgsi_full_declaration *decl)
154aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
155aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
156aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
157aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
158763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell       decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
159763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell       decl->Semantic.Index == 0) {
160fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      aactx->colorOutput = decl->Range.First;
161aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
162aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   else if (decl->Declaration.File == TGSI_FILE_SAMPLER) {
1636579440ea98e61871fe781c1c9c681645ddcc075Brian      uint i;
164fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      for (i = decl->Range.First;
165fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell           i <= decl->Range.Last; i++) {
1666579440ea98e61871fe781c1c9c681645ddcc075Brian         aactx->samplersUsed |= 1 << i;
1676579440ea98e61871fe781c1c9c681645ddcc075Brian      }
168aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
169aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
170fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      if ((int) decl->Range.Last > aactx->maxInput)
171fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell         aactx->maxInput = decl->Range.Last;
172763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
173763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell           (int) decl->Semantic.Index > aactx->maxGeneric) {
174763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell         aactx->maxGeneric = decl->Semantic.Index;
175aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      }
176aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
177aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
178aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      uint i;
179fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      for (i = decl->Range.First;
180fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell           i <= decl->Range.Last; i++) {
181aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         aactx->tempsUsed |= (1 << i);
182aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      }
183aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
184aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
185aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ctx->emit_declaration(ctx, decl);
186aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
187aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
188aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
189aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
1906579440ea98e61871fe781c1c9c681645ddcc075Brian * Find the lowest zero bit in the given word, or -1 if bitfield is all ones.
1916579440ea98e61871fe781c1c9c681645ddcc075Brian */
1926579440ea98e61871fe781c1c9c681645ddcc075Brianstatic int
1936579440ea98e61871fe781c1c9c681645ddcc075Brianfree_bit(uint bitfield)
1946579440ea98e61871fe781c1c9c681645ddcc075Brian{
195c173eb990a20611ac47c1727e1fb11d7fd3aa0c4Brian Paul   return ffs(~bitfield) - 1;
1966579440ea98e61871fe781c1c9c681645ddcc075Brian}
1976579440ea98e61871fe781c1c9c681645ddcc075Brian
1986579440ea98e61871fe781c1c9c681645ddcc075Brian
1996579440ea98e61871fe781c1c9c681645ddcc075Brian/**
200aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * TGSI instruction transform callback.
201aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Replace writes to result.color w/ a temp reg.
202aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Upon END instruction, insert texture sampling code for antialiasing.
203aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
204aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
205aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaa_transform_inst(struct tgsi_transform_context *ctx,
206aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian                  struct tgsi_full_instruction *inst)
207aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
208aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
209aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
210aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   if (aactx->firstInstruction) {
211aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* emit our new declarations before the first instruction */
212aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
213aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      struct tgsi_full_declaration decl;
214aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      uint i;
215aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
2166579440ea98e61871fe781c1c9c681645ddcc075Brian      /* find free sampler */
2176579440ea98e61871fe781c1c9c681645ddcc075Brian      aactx->freeSampler = free_bit(aactx->samplersUsed);
2186579440ea98e61871fe781c1c9c681645ddcc075Brian      if (aactx->freeSampler >= PIPE_MAX_SAMPLERS)
2196579440ea98e61871fe781c1c9c681645ddcc075Brian         aactx->freeSampler = PIPE_MAX_SAMPLERS - 1;
2206579440ea98e61871fe781c1c9c681645ddcc075Brian
221aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* find two free temp regs */
222aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      for (i = 0; i < 32; i++) {
223aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         if ((aactx->tempsUsed & (1 << i)) == 0) {
224aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            /* found a free temp */
225aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            if (aactx->colorTemp < 0)
226aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               aactx->colorTemp  = i;
227aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            else if (aactx->texTemp < 0)
228aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               aactx->texTemp  = i;
229aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            else
230aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               break;
231aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         }
232aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      }
233aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      assert(aactx->colorTemp >= 0);
234aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      assert(aactx->texTemp >= 0);
235aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
236aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* declare new generic input/texcoord */
237aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl = tgsi_default_full_declaration();
238aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl.Declaration.File = TGSI_FILE_INPUT;
239c2ff3a66a1d9fe0b5303ded0503323a73a6a7391Michal Krol      /* XXX this could be linear... */
2401279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez      decl.Declaration.Interpolate = 1;
241aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl.Declaration.Semantic = 1;
242763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
243763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      decl.Semantic.Index = aactx->maxGeneric + 1;
244fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
245fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = aactx->maxInput + 1;
2461279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez      decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
247aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_declaration(ctx, &decl);
248aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
249aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* declare new sampler */
250aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl = tgsi_default_full_declaration();
251aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl.Declaration.File = TGSI_FILE_SAMPLER;
252fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
253fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = aactx->freeSampler;
254aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_declaration(ctx, &decl);
255aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
256aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* declare new temp regs */
257aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl = tgsi_default_full_declaration();
258aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl.Declaration.File = TGSI_FILE_TEMPORARY;
259fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
260fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = aactx->texTemp;
261aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_declaration(ctx, &decl);
262aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
263aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl = tgsi_default_full_declaration();
264aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      decl.Declaration.File = TGSI_FILE_TEMPORARY;
265fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
266fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = aactx->colorTemp;
267aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_declaration(ctx, &decl);
268aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
269aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      aactx->firstInstruction = FALSE;
270aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
271aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
272aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   if (inst->Instruction.Opcode == TGSI_OPCODE_END &&
273aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian       aactx->colorOutput != -1) {
274aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      struct tgsi_full_instruction newInst;
275aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
276aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* TEX */
277aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst = tgsi_default_full_instruction();
278aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.Opcode = TGSI_OPCODE_TEX;
279aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumDstRegs = 1;
2805b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
2815b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = aactx->texTemp;
282aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumSrcRegs = 2;
283ba1ca28cc62fed71c77902b95ae4ed36c6bf25f8Keith Whitwell      newInst.Instruction.Texture = TRUE;
2847d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell      newInst.Texture.Texture = TGSI_TEXTURE_2D;
28591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
28691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = aactx->maxInput + 1;
28791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_SAMPLER;
28891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = aactx->freeSampler;
289aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
290aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_instruction(ctx, &newInst);
291aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
292aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* MOV rgb */
293aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst = tgsi_default_full_instruction();
294aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
295aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumDstRegs = 1;
2965b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
2975b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = aactx->colorOutput;
2985b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
299aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumSrcRegs = 1;
30091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
30191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = aactx->colorTemp;
302aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_instruction(ctx, &newInst);
303aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
304aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* MUL alpha */
305aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst = tgsi_default_full_instruction();
306aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
307aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumDstRegs = 1;
3085b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
3095b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = aactx->colorOutput;
3105b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
311aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumSrcRegs = 2;
31291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
31391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = aactx->colorTemp;
31491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
31591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = aactx->texTemp;
316aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_instruction(ctx, &newInst);
317aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
318aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* END */
319aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst = tgsi_default_full_instruction();
320aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.Opcode = TGSI_OPCODE_END;
321aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumDstRegs = 0;
322aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      newInst.Instruction.NumSrcRegs = 0;
323aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_instruction(ctx, &newInst);
324aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
325aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   else {
326aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* Not an END instruction.
327aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian       * Look for writes to result.color and replace with colorTemp reg.
328aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian       */
329aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      uint i;
330aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
331aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
3327d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         struct tgsi_full_dst_register *dst = &inst->Dst[i];
3335b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell         if (dst->Register.File == TGSI_FILE_OUTPUT &&
3345b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell             dst->Register.Index == aactx->colorOutput) {
3355b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell            dst->Register.File = TGSI_FILE_TEMPORARY;
3365b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell            dst->Register.Index = aactx->colorTemp;
337aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         }
338aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      }
339aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
340aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ctx->emit_instruction(ctx, inst);
341aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
342aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
343aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
344aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
345aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
346aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Generate the frag shader we'll use for drawing AA lines.
347aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * This will be the user's shader plus some texture/modulate instructions.
348aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
349a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwellstatic boolean
350aceeb80d4f706980aaf71b8e098d4c6718d8ac90Briangenerate_aaline_fs(struct aaline_stage *aaline)
351aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
352e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = aaline->stage.draw->pipe;
353aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   const struct pipe_shader_state *orig_fs = &aaline->fs->state;
354aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct pipe_shader_state aaline_fs;
355aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aa_transform_context transform;
3566f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul   const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
357aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
358aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline_fs = *orig_fs; /* copy to init */
3596f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul   aaline_fs.tokens = tgsi_alloc_tokens(newLen);
360a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   if (aaline_fs.tokens == NULL)
361a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell      return FALSE;
362aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
363aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   memset(&transform, 0, sizeof(transform));
364aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.colorOutput = -1;
365aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.maxInput = -1;
366aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.maxGeneric = -1;
367aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.colorTemp = -1;
368aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.texTemp = -1;
369aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.firstInstruction = TRUE;
370aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.base.transform_instruction = aa_transform_inst;
371aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   transform.base.transform_declaration = aa_transform_decl;
372aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
373aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tgsi_transform_shader(orig_fs->tokens,
374aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian                         (struct tgsi_token *) aaline_fs.tokens,
3756f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul                         newLen, &transform.base);
376aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
377aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#if 0 /* DEBUG */
378102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   debug_printf("draw_aaline, orig shader:\n");
379aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tgsi_dump(orig_fs->tokens, 0);
380102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   debug_printf("draw_aaline, new shader:\n");
381aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tgsi_dump(aaline_fs.tokens, 0);
382aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian#endif
383aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
3846579440ea98e61871fe781c1c9c681645ddcc075Brian   aaline->fs->sampler_unit = transform.freeSampler;
3856579440ea98e61871fe781c1c9c681645ddcc075Brian
386451dfe541393c553e78c9c037a907c1214d3b4edBrian Paul   aaline->fs->aaline_fs = aaline->driver_create_fs_state(pipe, &aaline_fs);
38769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline->fs->aaline_fs == NULL)
388003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell      goto fail;
389aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
3908cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul   aaline->fs->generic_attrib = transform.maxGeneric + 1;
391003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   FREE((void *)aaline_fs.tokens);
392a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   return TRUE;
393003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell
394003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwellfail:
395003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   FREE((void *)aaline_fs.tokens);
396003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   return FALSE;
397aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
398aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
399aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
400aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
401aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Create the texture map we'll use for antialiasing the lines.
402aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
40369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwellstatic boolean
404aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_create_texture(struct aaline_stage *aaline)
405aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
406e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = aaline->stage.draw->pipe;
4076f715dcc219071e574e363a9db4365c9c31ebbd3Brian   struct pipe_screen *screen = pipe->screen;
408287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource texTemp;
409f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   struct pipe_sampler_view viewTempl;
410aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   uint level;
411aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
412aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   memset(&texTemp, 0, sizeof(texTemp));
413aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   texTemp.target = PIPE_TEXTURE_2D;
41454f94a790e4488445347abcff9a636a9c440d7f9Brian Paul   texTemp.format = PIPE_FORMAT_A8_UNORM; /* XXX verify supported by driver! */
415aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   texTemp.last_level = MAX_TEXTURE_LEVEL;
41607eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca   texTemp.width0 = 1 << TEXTURE_SIZE_LOG2;
41707eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca   texTemp.height0 = 1 << TEXTURE_SIZE_LOG2;
418683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell   texTemp.depth0 = 1;
4194c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   texTemp.array_size = 1;
4200639765b2850739af1678f10fc0c5706d5827776Brian Paul   texTemp.bind = PIPE_BIND_SAMPLER_VIEW;
421aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
422287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   aaline->texture = screen->resource_create(screen, &texTemp);
42369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (!aaline->texture)
42469ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      return FALSE;
425aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
426f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   u_sampler_view_default_template(&viewTempl,
427f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                   aaline->texture,
428f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                   aaline->texture->format);
429f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   aaline->sampler_view = pipe->create_sampler_view(pipe,
430f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                                    aaline->texture,
431f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                                    &viewTempl);
432f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   if (!aaline->sampler_view) {
433f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      return FALSE;
434f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   }
435f6106566081978f663cf08e54bb8908cb58a5316Michal Krol
436aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* Fill in mipmap images.
437aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    * Basically each level is solid opaque, except for the outermost
438aa9003e20e91213bb97269bcd35961f0c2e9791bBrian Paul    * texels which are zero.  Special case the 1x1 and 2x2 levels
439aa9003e20e91213bb97269bcd35961f0c2e9791bBrian Paul    * (though, those levels shouldn't be used - see the max_lod setting).
440aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
441aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   for (level = 0; level <= MAX_TEXTURE_LEVEL; level++) {
4424617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      struct pipe_transfer *transfer;
443287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      struct pipe_box box;
444683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell      const uint size = u_minify(aaline->texture->width0, level);
445aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      ubyte *data;
446aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      uint i, j;
447aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
448683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell      assert(aaline->texture->width0 == aaline->texture->height0);
449aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
450287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      u_box_origin_2d( size, size, &box );
451287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
452c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell      /* This texture is new, no need to flush.
453c9ed86a96483063f3d6789ed16645a3dca77d726Keith Whitwell       */
454287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      transfer = pipe->get_transfer(pipe,
4554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    aaline->texture,
4564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    level,
4574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    PIPE_TRANSFER_WRITE,
4584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    &box);
459287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell
460b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      data = pipe->transfer_map(pipe, transfer);
46169ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      if (data == NULL)
46269ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell         return FALSE;
463aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
464aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      for (i = 0; i < size; i++) {
465aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         for (j = 0; j < size; j++) {
466228f6b978804268a482718e762ebfccbba784949Brian            ubyte d;
467aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            if (size == 1) {
468aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               d = 255;
469aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            }
470aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            else if (size == 2) {
471aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               d = 200; /* tuneable */
472aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            }
473aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            else if (i == 0 || j == 0 || i == size - 1 || j == size - 1) {
474413511f7967260c61085a4fa61bebdcc385cf7caBrian Paul               d = 35;  /* edge texel */
475aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            }
476aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            else {
477aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian               d = 255;
478aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian            }
4794617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer            data[i * transfer->stride + j] = d;
480aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian         }
481aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      }
482aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
483aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      /* unmap */
484b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, transfer);
485287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, transfer);
486aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
48769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   return TRUE;
488aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
489aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
490aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
491aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
492aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Create the sampler CSO that'll be used for antialiasing.
493aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * By using a mipmapped texture, we don't have to generate a different
494aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * texture image for each line size.
495aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
49669ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwellstatic boolean
497aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_create_sampler(struct aaline_stage *aaline)
498aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
499aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct pipe_sampler_state sampler;
500e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = aaline->stage.draw->pipe;
501aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
502aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   memset(&sampler, 0, sizeof(sampler));
503aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
504aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
505aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
506aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR;
507aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.min_img_filter = PIPE_TEX_FILTER_LINEAR;
508aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.mag_img_filter = PIPE_TEX_FILTER_LINEAR;
509aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.normalized_coords = 1;
510aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   sampler.min_lod = 0.0f;
51107eb660fc92b63213b542d47671b0d944286b77aJosé Fonseca   sampler.max_lod = MAX_TEXTURE_LEVEL;
512aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
513aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->sampler_cso = pipe->create_sampler_state(pipe, &sampler);
51469ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline->sampler_cso == NULL)
51569ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      return FALSE;
51669ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
51769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   return TRUE;
518aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
519aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
520aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
521aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
522aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * When we're about to draw our first AA line in a batch, this function is
523aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * called to tell the driver to bind our modified fragment shader.
524aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
525a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwellstatic boolean
526aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianbind_aaline_fragment_shader(struct aaline_stage *aaline)
527aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
52814d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   struct draw_context *draw = aaline->stage.draw;
529e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
53014d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
531a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   if (!aaline->fs->aaline_fs &&
532a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell       !generate_aaline_fs(aaline))
533a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell      return FALSE;
534a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell
53514d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = TRUE;
536e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aaline->driver_bind_fs_state(pipe, aaline->fs->aaline_fs);
53714d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = FALSE;
53814d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
539a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   return TRUE;
540aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
541aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
542aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
543aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
544aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic INLINE struct aaline_stage *
545aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_stage( struct draw_stage *stage )
546aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
547aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   return (struct aaline_stage *) stage;
548aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
549aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
550aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
551aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
552aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Draw a wide line by drawing a quad, using geometry which will
553aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * fullfill GL's antialiased line requirements.
554aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
555aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
556aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_line(struct draw_stage *stage, struct prim_header *header)
557aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
558aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   const struct aaline_stage *aaline = aaline_stage(stage);
559aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   const float half_width = aaline->half_line_width;
560aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct prim_header tri;
561aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct vertex_header *v[8];
562aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   uint texPos = aaline->tex_slot;
5632161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   uint posPos = aaline->pos_slot;
564aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   float *pos, *tex;
5652161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   float dx = header->v[1]->data[posPos][0] - header->v[0]->data[posPos][0];
5662161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   float dy = header->v[1]->data[posPos][1] - header->v[0]->data[posPos][1];
567228f6b978804268a482718e762ebfccbba784949Brian   double a = atan2(dy, dx);
568228f6b978804268a482718e762ebfccbba784949Brian   float c_a = (float) cos(a), s_a = (float) sin(a);
569aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   uint i;
570aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
571aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* XXX the ends of lines aren't quite perfect yet, but probably passable */
572228f6b978804268a482718e762ebfccbba784949Brian   dx = 0.5F * half_width;
573aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   dy = half_width;
574aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
575aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* allocate/dup new verts */
576aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   for (i = 0; i < 8; i++) {
577aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      v[i] = dup_vert(stage, header->v[i/4], i);
578aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   }
579aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
580aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /*
581aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    * Quad strip for line from v0 to v1 (*=endpoints):
582aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *
583aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  1   3                     5   7
584aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  +---+---------------------+---+
585aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  |                             |
586aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  | *v0                     v1* |
587aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  |                             |
588aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  +---+---------------------+---+
589aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    *  0   2                     4   6
590aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
591aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
592aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* new verts */
5932161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[0]->data[posPos];
594aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += (-dx * c_a -  dy * s_a);
595aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += (-dx * s_a +  dy * c_a);
596aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
5972161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[1]->data[posPos];
598aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += (-dx * c_a - -dy * s_a);
599aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += (-dx * s_a + -dy * c_a);
600aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6012161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[2]->data[posPos];
602aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += ( dx * c_a -  dy * s_a);
603aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += ( dx * s_a +  dy * c_a);
604aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6052161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[3]->data[posPos];
606aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += ( dx * c_a - -dy * s_a);
607aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += ( dx * s_a + -dy * c_a);
608aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6092161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[4]->data[posPos];
610aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += (-dx * c_a -  dy * s_a);
611aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += (-dx * s_a +  dy * c_a);
612aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6132161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[5]->data[posPos];
614aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += (-dx * c_a - -dy * s_a);
615aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += (-dx * s_a + -dy * c_a);
616aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6172161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[6]->data[posPos];
618aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += ( dx * c_a -  dy * s_a);
619aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += ( dx * s_a +  dy * c_a);
620aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6212161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[7]->data[posPos];
622aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[0] += ( dx * c_a - -dy * s_a);
623aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pos[1] += ( dx * s_a + -dy * c_a);
624aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
625aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* new texcoords */
626aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[0]->data[texPos];
627aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, 0, 0, 0, 1);
628aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
629aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[1]->data[texPos];
630aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, 0, 1, 0, 1);
631aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
632aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[2]->data[texPos];
633aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, .5, 0, 0, 1);
634aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
635aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[3]->data[texPos];
636aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, .5, 1, 0, 1);
637aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
638aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[4]->data[texPos];
639aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, .5, 0, 0, 1);
640aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
641aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[5]->data[texPos];
642aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, .5, 1, 0, 1);
643aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
644aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[6]->data[texPos];
645aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, 1, 0, 0, 1);
646aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
647aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tex = v[7]->data[texPos];
648aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   ASSIGN_4V(tex, 1, 1, 0, 1);
649aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
650aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* emit 6 tris for the quad strip */
651aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[2];  tri.v[1] = v[1];  tri.v[2] = v[0];
652aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
653aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
654aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[3];  tri.v[1] = v[1];  tri.v[2] = v[2];
655aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
656aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
657aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[4];  tri.v[1] = v[3];  tri.v[2] = v[2];
658aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
659aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
660aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[5];  tri.v[1] = v[3];  tri.v[2] = v[4];
661aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
662aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
663aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[6];  tri.v[1] = v[5];  tri.v[2] = v[4];
664aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
665aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
666aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   tri.v[0] = v[7];  tri.v[1] = v[5];  tri.v[2] = v[6];
667aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->tri( stage->next, &tri );
668aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
669aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
670aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
671aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
672aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_first_line(struct draw_stage *stage, struct prim_header *header)
673aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
674aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   auto struct aaline_stage *aaline = aaline_stage(stage);
675aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct draw_context *draw = stage->draw;
676e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
677e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   const struct pipe_rasterizer_state *rast = draw->rasterizer;
6786579440ea98e61871fe781c1c9c681645ddcc075Brian   uint num_samplers;
679e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   void *r;
680aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
681aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   assert(draw->rasterizer->line_smooth);
682aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
683aa9003e20e91213bb97269bcd35961f0c2e9791bBrian Paul   if (draw->rasterizer->line_width <= 2.2)
684aa9003e20e91213bb97269bcd35961f0c2e9791bBrian Paul      aaline->half_line_width = 1.1f;
685aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   else
686aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian      aaline->half_line_width = 0.5f * draw->rasterizer->line_width;
687aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
688aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /*
6898cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul    * Bind (generate) our fragprog, sampler and texture
690aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
691a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   if (!bind_aaline_fragment_shader(aaline)) {
692a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell      stage->line = draw_pipe_passthrough_line;
69330b4dc29091347252bc61d3be9370db0a45c16c3Keith Whitwell      stage->line(stage, header);
694a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell      return;
695a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   }
696aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
6978cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul   /* update vertex attrib info */
69889d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   aaline->pos_slot = draw_current_shader_position_output(draw);;
6998cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul
700e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   /* allocate the extra post-transformed vertex attribute */
701102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   aaline->tex_slot = draw_alloc_extra_vertex_attrib(draw,
702102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca                                                     TGSI_SEMANTIC_GENERIC,
703102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca                                                     aaline->fs->generic_attrib);
7048cb85807d3bd42cb0e511970e4b409c542d2716bBrian Paul
7056579440ea98e61871fe781c1c9c681645ddcc075Brian   /* how many samplers? */
7066579440ea98e61871fe781c1c9c681645ddcc075Brian   /* we'll use sampler/texture[pstip->sampler_unit] for the stipple */
707f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   num_samplers = MAX2(aaline->num_sampler_views, aaline->num_samplers);
7086579440ea98e61871fe781c1c9c681645ddcc075Brian   num_samplers = MAX2(num_samplers, aaline->fs->sampler_unit + 1);
7096579440ea98e61871fe781c1c9c681645ddcc075Brian
7106579440ea98e61871fe781c1c9c681645ddcc075Brian   aaline->state.sampler[aaline->fs->sampler_unit] = aaline->sampler_cso;
711f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   pipe_sampler_view_reference(&aaline->state.sampler_views[aaline->fs->sampler_unit],
712f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                               aaline->sampler_view);
7134528287e040415c2071012d02f20979ff995c754Keith Whitwell
71414d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = TRUE;
7156579440ea98e61871fe781c1c9c681645ddcc075Brian   aaline->driver_bind_sampler_states(pipe, num_samplers, aaline->state.sampler);
716f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   aaline->driver_set_sampler_views(pipe, num_samplers, aaline->state.sampler_views);
717e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
718e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   /* Disable triangle culling, stippling, unfilled mode etc. */
719e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
720e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   pipe->bind_rasterizer_state(pipe, r);
721e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
72214d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = FALSE;
723aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
724aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* now really draw first line */
725aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->line = aaline_line;
726aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->line(stage, header);
727aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
728aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
729aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
730aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
731aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_flush(struct draw_stage *stage, unsigned flags)
732aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
733aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct draw_context *draw = stage->draw;
734aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage(stage);
735e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
736aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
737aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->line = aaline_first_line;
738aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->flush( stage->next, flags );
739aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
74014d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   /* restore original frag shader, texture, sampler state */
74114d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = TRUE;
742edb19707951306447daef43c1ea3cacec5f211fbJosé Fonseca   aaline->driver_bind_fs_state(pipe, aaline->fs ? aaline->fs->driver_fs : NULL);
7434528287e040415c2071012d02f20979ff995c754Keith Whitwell   aaline->driver_bind_sampler_states(pipe, aaline->num_samplers,
7444528287e040415c2071012d02f20979ff995c754Keith Whitwell                                      aaline->state.sampler);
745f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   aaline->driver_set_sampler_views(pipe,
746f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                    aaline->num_sampler_views,
747f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                                    aaline->state.sampler_views);
748e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
749e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   /* restore original rasterizer state */
750e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   if (draw->rast_handle) {
751e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
752e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   }
753e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
75414d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = FALSE;
755aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
756e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   draw_remove_extra_vertex_attribs(draw);
757aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
758aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
759aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
760aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
761aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_reset_stipple_counter(struct draw_stage *stage)
762aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
763aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   stage->next->reset_stipple_counter( stage->next );
764aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
765aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
766aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
767aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
768aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_destroy(struct draw_stage *stage)
769aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
770dae7993afc56be1e71e600af60e01e51eab17edaBrian   struct aaline_stage *aaline = aaline_stage(stage);
771e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = stage->draw->pipe;
77221e614eabc5e6a502504f307f3710b4dd0417923Brian Paul   uint i;
77321e614eabc5e6a502504f307f3710b4dd0417923Brian Paul
77421e614eabc5e6a502504f307f3710b4dd0417923Brian Paul   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
775f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
77621e614eabc5e6a502504f307f3710b4dd0417923Brian Paul   }
777dae7993afc56be1e71e600af60e01e51eab17edaBrian
77869ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline->sampler_cso)
779e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      pipe->delete_sampler_state(pipe, aaline->sampler_cso);
780dae7993afc56be1e71e600af60e01e51eab17edaBrian
78169ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline->texture)
782287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe_resource_reference(&aaline->texture, NULL);
783dae7993afc56be1e71e600af60e01e51eab17edaBrian
784f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   if (aaline->sampler_view) {
785f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      pipe_sampler_view_reference(&aaline->sampler_view, NULL);
786f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   }
787f6106566081978f663cf08e54bb8908cb58a5316Michal Krol
788aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   draw_free_temp_verts( stage );
789dae7993afc56be1e71e600af60e01e51eab17edaBrian
7905349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   /* restore the old entry points */
7915349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->create_fs_state = aaline->driver_create_fs_state;
7925349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->bind_fs_state = aaline->driver_bind_fs_state;
7935349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->delete_fs_state = aaline->driver_delete_fs_state;
7945349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin
7955349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->bind_fragment_sampler_states = aaline->driver_bind_sampler_states;
7965349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->set_fragment_sampler_views = aaline->driver_set_sampler_views;
7975349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin
798aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   FREE( stage );
799aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
800aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
801aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
802aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic struct aaline_stage *
803aceeb80d4f706980aaf71b8e098d4c6718d8ac90Briandraw_aaline_stage(struct draw_context *draw)
804aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
805aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = CALLOC_STRUCT(aaline_stage);
80669ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline == NULL)
80769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      return NULL;
808aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
809aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.draw = draw;
810eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   aaline->stage.name = "aaline";
811aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.next = NULL;
812a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   aaline->stage.point = draw_pipe_passthrough_point;
813aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.line = aaline_first_line;
814a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   aaline->stage.tri = draw_pipe_passthrough_tri;
815aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.flush = aaline_flush;
816aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.reset_stipple_counter = aaline_reset_stipple_counter;
817aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->stage.destroy = aaline_destroy;
818aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
8191c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane   if (!draw_alloc_temp_verts( &aaline->stage, 8 ))
8201c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      goto fail;
8211c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane
822aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   return aaline;
82369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
82469ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell fail:
82569ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline)
8261c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      aaline->stage.destroy(&aaline->stage);
82769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
82869ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   return NULL;
829aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
830aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
831aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
832aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic struct aaline_stage *
833aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_stage_from_pipe(struct pipe_context *pipe)
834aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
83578220aea864c36038f8425ad9d8467d2a2bdea58Brian   struct draw_context *draw = (struct draw_context *) pipe->draw;
83678220aea864c36038f8425ad9d8467d2a2bdea58Brian   return aaline_stage(draw->pipeline.aaline);
837aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
838aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
839aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
840aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
841aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * This function overrides the driver's create_fs_state() function and
842aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * will typically be called by the state tracker.
843aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
844aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void *
845aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_create_fs_state(struct pipe_context *pipe,
846aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian                       const struct pipe_shader_state *fs)
847aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
848aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
849aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_fragment_shader *aafs = CALLOC_STRUCT(aaline_fragment_shader);
850e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
8510d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (aafs == NULL)
8520d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      return NULL;
853aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
854fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca   aafs->state.tokens = tgsi_dup_tokens(fs->tokens);
855aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
8560d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   /* pass-through */
857e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aafs->driver_fs = aaline->driver_create_fs_state(pipe, fs);
858aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
859aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   return aafs;
860aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
861aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
862aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
863aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
864aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_bind_fs_state(struct pipe_context *pipe, void *fs)
865aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
866aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
867aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
86814d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
869aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* save current */
870aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->fs = aafs;
871aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* pass-through */
872e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aaline->driver_bind_fs_state(pipe, (aafs ? aafs->driver_fs : NULL));
873aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
874aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
875aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
876aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
877aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianaaline_delete_fs_state(struct pipe_context *pipe, void *fs)
878aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
879aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
880aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_fragment_shader *aafs = (struct aaline_fragment_shader *) fs;
881e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
882aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* pass-through */
883e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aaline->driver_delete_fs_state(pipe, aafs->driver_fs);
8841aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell
8851aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell   if (aafs->aaline_fs)
886e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      aaline->driver_delete_fs_state(pipe, aafs->aaline_fs);
8871aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell
888fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca   FREE((void*)aafs->state.tokens);
889fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca
890aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   FREE(aafs);
891aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
892aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
893aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
894aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
8954528287e040415c2071012d02f20979ff995c754Keith Whitwellaaline_bind_sampler_states(struct pipe_context *pipe,
8964528287e040415c2071012d02f20979ff995c754Keith Whitwell                           unsigned num, void **sampler)
897aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
898aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
89914d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
900aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* save current */
9014528287e040415c2071012d02f20979ff995c754Keith Whitwell   memcpy(aaline->state.sampler, sampler, num * sizeof(void *));
9024528287e040415c2071012d02f20979ff995c754Keith Whitwell   aaline->num_samplers = num;
90314d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
904aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* pass-through */
905e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aaline->driver_bind_sampler_states(pipe, num, sampler);
906aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
907aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
908aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
909aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brianstatic void
910f6106566081978f663cf08e54bb8908cb58a5316Michal Krolaaline_set_sampler_views(struct pipe_context *pipe,
911f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                         unsigned num,
912f6106566081978f663cf08e54bb8908cb58a5316Michal Krol                         struct pipe_sampler_view **views)
913aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
914aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline = aaline_stage_from_pipe(pipe);
9157f430293772f201a59bcf62edd1ed4f942f8be29Brian   uint i;
9167f430293772f201a59bcf62edd1ed4f942f8be29Brian
917aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* save current */
9187f430293772f201a59bcf62edd1ed4f942f8be29Brian   for (i = 0; i < num; i++) {
919f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      pipe_sampler_view_reference(&aaline->state.sampler_views[i], views[i]);
9207f430293772f201a59bcf62edd1ed4f942f8be29Brian   }
92121e614eabc5e6a502504f307f3710b4dd0417923Brian Paul   for ( ; i < PIPE_MAX_SAMPLERS; i++) {
922f6106566081978f663cf08e54bb8908cb58a5316Michal Krol      pipe_sampler_view_reference(&aaline->state.sampler_views[i], NULL);
92321e614eabc5e6a502504f307f3710b4dd0417923Brian Paul   }
924f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   aaline->num_sampler_views = num;
9257f430293772f201a59bcf62edd1ed4f942f8be29Brian
926aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* pass-through */
9278f3bdeaad610d7d5a5c6e73e1e9c721219595754Brian Paul   aaline->driver_set_sampler_views(pipe, num, views);
928aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
929aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
930aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
931aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian/**
932aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * Called by drivers that want to install this AA line prim stage
933aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * into the draw module's pipeline.  This will not be used if the
934aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian * hardware has native support for AA lines.
935aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian */
93669ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwellboolean
937aceeb80d4f706980aaf71b8e098d4c6718d8ac90Briandraw_install_aaline_stage(struct draw_context *draw, struct pipe_context *pipe)
938aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian{
939aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   struct aaline_stage *aaline;
940aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
94178220aea864c36038f8425ad9d8467d2a2bdea58Brian   pipe->draw = (void *) draw;
94278220aea864c36038f8425ad9d8467d2a2bdea58Brian
943aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /*
944aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    * Create / install AA line drawing / prim stage
945aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian    */
946aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline = draw_aaline_stage( draw );
94769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (!aaline)
94869ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      goto fail;
949aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
950aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* create special texture, sampler state */
95169ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (!aaline_create_texture(aaline))
95269ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      goto fail;
95369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
95469ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (!aaline_create_sampler(aaline))
95569ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      goto fail;
956aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
957aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* save original driver functions */
958aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->driver_create_fs_state = pipe->create_fs_state;
959aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->driver_bind_fs_state = pipe->bind_fs_state;
960aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   aaline->driver_delete_fs_state = pipe->delete_fs_state;
961aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
962f33c064f32bf3635becd1b2019f670abe7a35ab3Michal Krol   aaline->driver_bind_sampler_states = pipe->bind_fragment_sampler_states;
963f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   aaline->driver_set_sampler_views = pipe->set_fragment_sampler_views;
964aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
965aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   /* override the driver's functions */
966aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pipe->create_fs_state = aaline_create_fs_state;
967aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pipe->bind_fs_state = aaline_bind_fs_state;
968aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian   pipe->delete_fs_state = aaline_delete_fs_state;
969aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian
970f33c064f32bf3635becd1b2019f670abe7a35ab3Michal Krol   pipe->bind_fragment_sampler_states = aaline_bind_sampler_states;
971f6106566081978f663cf08e54bb8908cb58a5316Michal Krol   pipe->set_fragment_sampler_views = aaline_set_sampler_views;
97269ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
97369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   /* Install once everything is known to be OK:
97469ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell    */
97569ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   draw->pipeline.aaline = &aaline->stage;
97669ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
97769ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   return TRUE;
97869ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
97969ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell fail:
98069ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   if (aaline)
98169ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell      aaline->stage.destroy( &aaline->stage );
98269ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell
98369ecc2a577dc45451d56cee3e41cb6e7e542b097Keith Whitwell   return FALSE;
984aceeb80d4f706980aaf71b8e098d4c6718d8ac90Brian}
985