1eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**************************************************************************
2eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
3eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * All Rights Reserved.
5eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
6eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Permission is hereby granted, free of charge, to any person obtaining a
7eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * copy of this software and associated documentation files (the
8eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * "Software"), to deal in the Software without restriction, including
9eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * without limitation the rights to use, copy, modify, merge, publish,
10eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * distribute, sub license, and/or sell copies of the Software, and to
11eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * permit persons to whom the Software is furnished to do so, subject to
12eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * the following conditions:
13eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
14eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * The above copyright notice and this permission notice (including the
15eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * next paragraph) shall be included in all copies or substantial portions
16eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * of the Software.
17eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
18eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
26eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian **************************************************************************/
27eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
28eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
29eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * AA point stage:  AA points are converted to quads and rendered with a
30eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * special fragment shader.  Another approach would be to use a texture
31eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * map image of a point, but experiments indicate the quality isn't nearly
32eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * as good as this approach.
33eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
34eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Note: this looks a lot like draw_aaline.c but there's actually little
35eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * if any code that can be shared.
36eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian *
37eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Authors:  Brian Paul
38eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
39eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
40eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
41eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#include "pipe/p_context.h"
42eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#include "pipe/p_defines.h"
43eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#include "pipe/p_shader_tokens.h"
44eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
45c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_transform.h"
46c208a2c791fa24c7c5887fc496738cbddbfafc72José Fonseca#include "tgsi/tgsi_dump.h"
47eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
484f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_math.h"
494f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
504f25420bdd834e81a3e22733304efc5261c2998aBrian Paul
51eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#include "draw_context.h"
52280bcff1fa200b790d8712946a4ffbaa47a67433Keith Whitwell#include "draw_vs.h"
53507fbe2d327efb8d608ce8e07436b97321560808Keith Whitwell#include "draw_pipe.h"
54eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
55eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
566f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul/** Approx number of new tokens for instructions in aa_transform_inst() */
576f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul#define NUM_NEW_TOKENS 200
586f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul
596f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul
60eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/*
61eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Enabling NORMALIZE might give _slightly_ better results.
62eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Basically, it controls whether we compute distance as d=sqrt(x*x+y*y) or
63eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * d=x*x+y*y.  Since we're working with a unit circle, the later seems
64eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * close enough and saves some costly instructions.
65eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
66eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#define NORMALIZE 0
67eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
68eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
69eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
70eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Subclass of pipe_shader_state to carry extra fragment shader info.
71eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
72eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstruct aapoint_fragment_shader
73eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
74eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct pipe_shader_state state;
75eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   void *driver_fs;   /**< the regular shader */
76eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   void *aapoint_fs;  /**< the aa point-augmented shader */
77e55dccd0bfc41dbcf306f864c01758f8e28fc660Brian   int generic_attrib; /**< The generic input attrib/texcoord we'll use */
78eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian};
79eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
80eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
81eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
82eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Subclass of draw_stage
83eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
84eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstruct aapoint_stage
85eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
86eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct draw_stage stage;
87eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
883d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   /** half of pipe_rasterizer_state::point_size */
89eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   float radius;
90eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
913d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   /** vertex attrib slot containing point size */
923d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   int psize_slot;
933d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul
94eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /** this is the vertex attrib slot for the new texcoords */
95eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   uint tex_slot;
963d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul
973d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   /** vertex attrib slot containing position */
982161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   uint pos_slot;
99eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
1003d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   /** Currently bound fragment shader */
101eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_fragment_shader *fs;
102eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
103eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /*
104eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * Driver interface/override functions
105eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    */
106eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   void * (*driver_create_fs_state)(struct pipe_context *,
107eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                                    const struct pipe_shader_state *);
108eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   void (*driver_bind_fs_state)(struct pipe_context *, void *);
109eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   void (*driver_delete_fs_state)(struct pipe_context *, void *);
110eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian};
111eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
112eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
113eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
114eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
115eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Subclass of tgsi_transform_context, used for transforming the
116eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * user's fragment shader to add the special AA instructions.
117eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
118eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstruct aa_transform_context {
119eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct tgsi_transform_context base;
120eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   uint tempsUsed;  /**< bitmask */
121eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   int colorOutput; /**< which output is the primary color */
122eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   int maxInput, maxGeneric;  /**< max input index found */
123eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   int tmp0, colorTemp;  /**< temp registers */
124eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   boolean firstInstruction;
125eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian};
126eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
127eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
128eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
129eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * TGSI declaration transform callback.
130eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Look for two free temp regs and available input reg for new texcoords.
131eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
132eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
133eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaa_transform_decl(struct tgsi_transform_context *ctx,
134eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                  struct tgsi_full_declaration *decl)
135eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
136eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
137eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
138eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (decl->Declaration.File == TGSI_FILE_OUTPUT &&
139763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell       decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
140763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell       decl->Semantic.Index == 0) {
141fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      aactx->colorOutput = decl->Range.First;
142eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
143eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   else if (decl->Declaration.File == TGSI_FILE_INPUT) {
144fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      if ((int) decl->Range.Last > aactx->maxInput)
145fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell         aactx->maxInput = decl->Range.Last;
146763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      if (decl->Semantic.Name == TGSI_SEMANTIC_GENERIC &&
147763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell           (int) decl->Semantic.Index > aactx->maxGeneric) {
148763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell         aactx->maxGeneric = decl->Semantic.Index;
149eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      }
150eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
151eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   else if (decl->Declaration.File == TGSI_FILE_TEMPORARY) {
152eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      uint i;
153fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      for (i = decl->Range.First;
154fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell           i <= decl->Range.Last; i++) {
155eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian         aactx->tempsUsed |= (1 << i);
156eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      }
157eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
158eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
159eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ctx->emit_declaration(ctx, decl);
160eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
161eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
162eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
163eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
164eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * TGSI instruction transform callback.
165eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Replace writes to result.color w/ a temp reg.
166eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Upon END instruction, insert texture sampling code for antialiasing.
167eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
168eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
169eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaa_transform_inst(struct tgsi_transform_context *ctx,
170eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                  struct tgsi_full_instruction *inst)
171eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
172eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aa_transform_context *aactx = (struct aa_transform_context *) ctx;
173eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct tgsi_full_instruction newInst;
174eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
175eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (aactx->firstInstruction) {
176eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* emit our new declarations before the first instruction */
177eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
178eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      struct tgsi_full_declaration decl;
179eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      const int texInput = aactx->maxInput + 1;
180eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      int tmp0;
181eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      uint i;
182eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
183eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* find two free temp regs */
184eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      for (i = 0; i < 32; i++) {
185eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian         if ((aactx->tempsUsed & (1 << i)) == 0) {
186eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            /* found a free temp */
187eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            if (aactx->tmp0 < 0)
188eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian               aactx->tmp0 = i;
189eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            else if (aactx->colorTemp < 0)
190eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian               aactx->colorTemp = i;
191eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            else
192eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian               break;
193eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian         }
194eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      }
195eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
196eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      assert(aactx->colorTemp != aactx->tmp0);
197eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
198eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      tmp0 = aactx->tmp0;
199eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
200eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* declare new generic input/texcoord */
201eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl = tgsi_default_full_declaration();
202eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl.Declaration.File = TGSI_FILE_INPUT;
203c2ff3a66a1d9fe0b5303ded0503323a73a6a7391Michal Krol      /* XXX this could be linear... */
2041279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez      decl.Declaration.Interpolate = 1;
205eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl.Declaration.Semantic = 1;
206763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      decl.Semantic.Name = TGSI_SEMANTIC_GENERIC;
207763426a0256f0ab06f8af53947bd630f8600183aKeith Whitwell      decl.Semantic.Index = aactx->maxGeneric + 1;
208fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
209fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = texInput;
2101279923d72942ee201fcc6ad40d552143f651f03Francisco Jerez      decl.Interp.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
211eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_declaration(ctx, &decl);
212eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
213eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* declare new temp regs */
214eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl = tgsi_default_full_declaration();
215eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl.Declaration.File = TGSI_FILE_TEMPORARY;
216fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
217fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = tmp0;
218eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_declaration(ctx, &decl);
219eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
220eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl = tgsi_default_full_declaration();
221eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      decl.Declaration.File = TGSI_FILE_TEMPORARY;
222fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.First =
223fe2b31e4a896167a33d267822b36eb2de0ceecbaKeith Whitwell      decl.Range.Last = aactx->colorTemp;
224eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_declaration(ctx, &decl);
225eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
226eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      aactx->firstInstruction = FALSE;
227eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
228eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
229eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /*
230eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       * Emit code to compute fragment coverage, kill if outside point radius
231eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       *
232eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       * Temp reg0 usage:
233eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       *  t0.x = distance of fragment from center point
23408a5f49644c4bfc62291c49718f2d18e58527d1dBrian       *  t0.y = boolean, is t0.x > 1.0, also misc temp usage
235eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       *  t0.z = temporary for computing 1/(1-k) value
236eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       *  t0.w = final coverage value
237eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       */
238eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
239eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* MUL t0.xy, tex, tex;  # compute x^2, y^2 */
240eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
241eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
242eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
2435b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
2445b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
2455b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XY;
246eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 2;
24791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
24891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = texInput;
24991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
25091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = texInput;
251eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
252eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
253eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* ADD t0.x, t0.x, t0.y;  # x^2 + y^2 */
254eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
255eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_ADD;
256eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
2575b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
2585b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
2595b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
260eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 2;
26191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
26291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
26391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_X;
26491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
26591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = tmp0;
26691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_Y;
267eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
268eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
269eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#if NORMALIZE  /* OPTIONAL normalization of length */
270eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* RSQ t0.x, t0.x; */
271eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
272eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_RSQ;
273eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
2745b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
2755b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
2765b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
277eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 1;
27891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
27991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
280eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
281eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
282eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* RCP t0.x, t0.x; */
283eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
284eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
285eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
2865b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
2875b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
2885b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_X;
289eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 1;
29091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
29191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
292eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
293eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#endif
294eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
295d0d5e6a22cca4aae487be6828d1dd87621929a7dKeith Whitwell      /* SGT t0.y, t0.xxxx, tex.wwww;  # bool b = d > 1 (NOTE tex.w == 1) */
296eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
297eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_SGT;
298eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
2995b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3005b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3015b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
302eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 2;
30391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
30491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
30591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
30691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
30791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = texInput;
30891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
309eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
310eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
3110c8f4c25ff1cdf8d4cad21789e0c73b41aa29c98Michal Krol      /* KIL -tmp0.yyyy;   # if -tmp0.y < 0, KILL */
312eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
3130c8f4c25ff1cdf8d4cad21789e0c73b41aa29c98Michal Krol      newInst.Instruction.Opcode = TGSI_OPCODE_KIL;
314eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 0;
315eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 1;
31691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
31791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
31891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Y;
31991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
32091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
32191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
32291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Negate = 1;
323eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
324eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
32508a5f49644c4bfc62291c49718f2d18e58527d1dBrian
32608a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* compute coverage factor = (1-d)/(1-k) */
32708a5f49644c4bfc62291c49718f2d18e58527d1dBrian
32808a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* SUB t0.z, tex.w, tex.z;  # m = 1 - k */
329eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
33008a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
33108a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumDstRegs = 1;
3325b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3335b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3345b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Z;
33508a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumSrcRegs = 2;
33691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
33791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = texInput;
33891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_W;
33991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
34091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = texInput;
34191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_Z;
34208a5f49644c4bfc62291c49718f2d18e58527d1dBrian      ctx->emit_instruction(ctx, &newInst);
34308a5f49644c4bfc62291c49718f2d18e58527d1dBrian
34408a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* RCP t0.z, t0.z;  # t0.z = 1 / m */
34508a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst = tgsi_default_full_instruction();
34608a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_RCP;
34708a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumDstRegs = 1;
3485b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3495b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3505b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Z;
35108a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumSrcRegs = 1;
35291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
35391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
35491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Z;
35508a5f49644c4bfc62291c49718f2d18e58527d1dBrian      ctx->emit_instruction(ctx, &newInst);
35608a5f49644c4bfc62291c49718f2d18e58527d1dBrian
35708a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* SUB t0.y, 1, t0.x;  # d = 1 - d */
35808a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst = tgsi_default_full_instruction();
35908a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_SUB;
36008a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumDstRegs = 1;
3615b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3625b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3635b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
36408a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumSrcRegs = 2;
36591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_INPUT;
36691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = texInput;
36791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_W;
36891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
36991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = tmp0;
37091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_X;
37108a5f49644c4bfc62291c49718f2d18e58527d1dBrian      ctx->emit_instruction(ctx, &newInst);
37208a5f49644c4bfc62291c49718f2d18e58527d1dBrian
37308a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* MUL t0.w, t0.y, t0.z;   # coverage = d * m */
37408a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst = tgsi_default_full_instruction();
37508a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
37608a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumDstRegs = 1;
3775b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3785b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3795b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
38008a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumSrcRegs = 2;
38191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
38291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
38391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
38491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
38591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = tmp0;
38691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_Z;
38708a5f49644c4bfc62291c49718f2d18e58527d1dBrian      ctx->emit_instruction(ctx, &newInst);
38808a5f49644c4bfc62291c49718f2d18e58527d1dBrian
38908a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* SLE t0.y, t0.x, tex.z;  # bool b = distance <= k */
39008a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst = tgsi_default_full_instruction();
39108a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_SLE;
392eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
3935b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
3945b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
3955b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_Y;
396eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 2;
39791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
39891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
39991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_X;
40091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
40191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = texInput;
40291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_Z;
403eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
404eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
40508a5f49644c4bfc62291c49718f2d18e58527d1dBrian      /* CMP t0.w, -t0.y, tex.w, t0.w;
40608a5f49644c4bfc62291c49718f2d18e58527d1dBrian       *  # if -t0.y < 0 then
40708a5f49644c4bfc62291c49718f2d18e58527d1dBrian       *       t0.w = 1
40808a5f49644c4bfc62291c49718f2d18e58527d1dBrian       *    else
40908a5f49644c4bfc62291c49718f2d18e58527d1dBrian       *       t0.w = t0.w
41008a5f49644c4bfc62291c49718f2d18e58527d1dBrian       */
411eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
41208a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.Opcode = TGSI_OPCODE_CMP;
41308a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumDstRegs = 1;
4145b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_TEMPORARY;
4155b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = tmp0;
4165b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
41708a5f49644c4bfc62291c49718f2d18e58527d1dBrian      newInst.Instruction.NumSrcRegs = 3;
41891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
41991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = tmp0;
42091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleX = TGSI_SWIZZLE_Y;
42191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleY = TGSI_SWIZZLE_Y;
42291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleZ = TGSI_SWIZZLE_Y;
42391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.SwizzleW = TGSI_SWIZZLE_Y;
42491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Negate = 1;
42591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_INPUT;
42691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = texInput;
42791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleX = TGSI_SWIZZLE_W;
42891a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleY = TGSI_SWIZZLE_W;
42991a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleZ = TGSI_SWIZZLE_W;
43091a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.SwizzleW = TGSI_SWIZZLE_W;
43191a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.File = TGSI_FILE_TEMPORARY;
43291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.Index = tmp0;
43391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.SwizzleX = TGSI_SWIZZLE_W;
43491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.SwizzleY = TGSI_SWIZZLE_W;
43591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.SwizzleZ = TGSI_SWIZZLE_W;
43691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[2].Register.SwizzleW = TGSI_SWIZZLE_W;
437eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
438eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
439eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
440eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
441eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (inst->Instruction.Opcode == TGSI_OPCODE_END) {
442eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* add alpha modulation code at tail of program */
443eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
444eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* MOV result.color.xyz, colorTemp; */
445eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
446eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_MOV;
447eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
4485b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
4495b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = aactx->colorOutput;
4505b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_XYZ;
451eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 1;
45291a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
45391a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = aactx->colorTemp;
454eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
455eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
456eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* MUL result.color.w, colorTemp, tmp0.w; */
457eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst = tgsi_default_full_instruction();
458eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.Opcode = TGSI_OPCODE_MUL;
459eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumDstRegs = 1;
4605b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.File = TGSI_FILE_OUTPUT;
4615b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.Index = aactx->colorOutput;
4625b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell      newInst.Dst[0].Register.WriteMask = TGSI_WRITEMASK_W;
463eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      newInst.Instruction.NumSrcRegs = 2;
46491a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.File = TGSI_FILE_TEMPORARY;
46591a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[0].Register.Index = aactx->colorTemp;
46691a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.File = TGSI_FILE_TEMPORARY;
46791a4e6d53f83c45c1da9240b6325011d96b61386Keith Whitwell      newInst.Src[1].Register.Index = aactx->tmp0;
468eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      ctx->emit_instruction(ctx, &newInst);
469eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
470eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   else {
471eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      /* Not an END instruction.
472eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       * Look for writes to result.color and replace with colorTemp reg.
473eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian       */
474eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      uint i;
475eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
476eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
4777d6c8f980d1e23ad6f557d650e89c715861a3b0cKeith Whitwell         struct tgsi_full_dst_register *dst = &inst->Dst[i];
4785b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell         if (dst->Register.File == TGSI_FILE_OUTPUT &&
4795b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell             dst->Register.Index == aactx->colorOutput) {
4805b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell            dst->Register.File = TGSI_FILE_TEMPORARY;
4815b0824dfe5eaf59fa87134e7482b3d147b262901Keith Whitwell            dst->Register.Index = aactx->colorTemp;
482eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian         }
483eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      }
484eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
485eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
486eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ctx->emit_instruction(ctx, inst);
487eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
488eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
489eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
490eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
4918437f5c763c1a1ac364d71426109c2b095bbcc72Brian Paul * Generate the frag shader we'll use for drawing AA points.
492eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * This will be the user's shader plus some texture/modulate instructions.
493eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
4940cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwellstatic boolean
495eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Briangenerate_aapoint_fs(struct aapoint_stage *aapoint)
496eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
497eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   const struct pipe_shader_state *orig_fs = &aapoint->fs->state;
498eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct pipe_shader_state aapoint_fs;
499eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aa_transform_context transform;
5006f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul   const uint newLen = tgsi_num_tokens(orig_fs->tokens) + NUM_NEW_TOKENS;
501e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = aapoint->stage.draw->pipe;
502eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
503eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint_fs = *orig_fs; /* copy to init */
5046f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul   aapoint_fs.tokens = tgsi_alloc_tokens(newLen);
5050cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (aapoint_fs.tokens == NULL)
5060cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell      return FALSE;
507eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
508eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   memset(&transform, 0, sizeof(transform));
509eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.colorOutput = -1;
510eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.maxInput = -1;
511eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.maxGeneric = -1;
512eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.colorTemp = -1;
513eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.tmp0 = -1;
514eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.firstInstruction = TRUE;
515eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.base.transform_instruction = aa_transform_inst;
516eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   transform.base.transform_declaration = aa_transform_decl;
517eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
518eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tgsi_transform_shader(orig_fs->tokens,
519eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                         (struct tgsi_token *) aapoint_fs.tokens,
5206f2e9651a1a460a1f564d30844cb2c9bced71da5Brian Paul                         newLen, &transform.base);
521eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
522232a41e19faa860f083e414cb1eb38c0617e9241Brian#if 0 /* DEBUG */
523102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   debug_printf("draw_aapoint, orig shader:\n");
524eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tgsi_dump(orig_fs->tokens, 0);
525102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   debug_printf("draw_aapoint, new shader:\n");
526eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tgsi_dump(aapoint_fs.tokens, 0);
527eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#endif
528eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
529eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->fs->aapoint_fs
530e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      = aapoint->driver_create_fs_state(pipe, &aapoint_fs);
5310cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (aapoint->fs->aapoint_fs == NULL)
532003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell      goto fail;
533eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
534e55dccd0bfc41dbcf306f864c01758f8e28fc660Brian   aapoint->fs->generic_attrib = transform.maxGeneric + 1;
535003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   FREE((void *)aapoint_fs.tokens);
5360cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   return TRUE;
537003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell
538003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwellfail:
539003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   FREE((void *)aapoint_fs.tokens);
540003cfd4dd2491675058c53a8f59553f2443be349Keith Whitwell   return FALSE;
541eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
542eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
543eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
544eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
5458437f5c763c1a1ac364d71426109c2b095bbcc72Brian Paul * When we're about to draw our first AA point in a batch, this function is
546eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * called to tell the driver to bind our modified fragment shader.
547eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
5480cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwellstatic boolean
549eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianbind_aapoint_fragment_shader(struct aapoint_stage *aapoint)
550eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
55114d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   struct draw_context *draw = aapoint->stage.draw;
552e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
55314d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
5540cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (!aapoint->fs->aapoint_fs &&
5550cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell       !generate_aapoint_fs(aapoint))
5560cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell      return FALSE;
5570cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
55814d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = TRUE;
559e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aapoint->driver_bind_fs_state(pipe, aapoint->fs->aapoint_fs);
56014d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = FALSE;
56114d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul
5620cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   return TRUE;
563eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
564eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
565eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
566eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
567eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic INLINE struct aapoint_stage *
568eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_stage( struct draw_stage *stage )
569eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
570eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   return (struct aapoint_stage *) stage;
571eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
572eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
573eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
574eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
575eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
576eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
577eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Draw an AA point by drawing a quad.
578eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
579eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
580eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_point(struct draw_stage *stage, struct prim_header *header)
581eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
582eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   const struct aapoint_stage *aapoint = aapoint_stage(stage);
583eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct prim_header tri;
584eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct vertex_header *v[4];
5853d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   const uint tex_slot = aapoint->tex_slot;
5863d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   const uint pos_slot = aapoint->pos_slot;
587eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   float radius, *pos, *tex;
588eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   uint i;
589eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   float k;
590eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
591eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (aapoint->psize_slot >= 0) {
592eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      radius = 0.5f * header->v[0]->data[aapoint->psize_slot][0];
593eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
594eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   else {
595eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      radius = aapoint->radius;
596eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
597eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
598eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /*
599eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * Note: the texcoords (generic attrib, really) we use are special:
600eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * The S and T components simply vary from -1 to +1.
601eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * The R component is k, below.
602eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * The Q component is 1.0 and will used as a handy constant in the
603eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * fragment shader.
604eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    */
605eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
606eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /*
607eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * k is the threshold distance from the point's center at which
608eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * we begin alpha attenuation (the coverage value).
609eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * Operating within a unit circle, we'll compute the fragment's
610eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * distance 'd' from the center point using the texcoords.
611eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * IF d > 1.0 THEN
612eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    *    KILL fragment
613eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * ELSE IF d > k THEN
614eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    *    compute coverage in [0,1] proportional to d in [k, 1].
615eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * ELSE
616eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    *    coverage = 1.0;  // full coverage
617eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * ENDIF
61808a5f49644c4bfc62291c49718f2d18e58527d1dBrian    *
61908a5f49644c4bfc62291c49718f2d18e58527d1dBrian    * Note: the ELSEIF and ELSE clauses are actually implemented with CMP to
62008a5f49644c4bfc62291c49718f2d18e58527d1dBrian    * avoid using IF/ELSE/ENDIF TGSI opcodes.
621eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    */
622eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
623eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#if !NORMALIZE
624e9bb63c8e20361597463b2f7f88d84fe2770c8b9José Fonseca   k = 1.0f / radius;
625e9bb63c8e20361597463b2f7f88d84fe2770c8b9José Fonseca   k = 1.0f - 2.0f * k + k * k;
626eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#else
627e9bb63c8e20361597463b2f7f88d84fe2770c8b9José Fonseca   k = 1.0f - 1.0f / radius;
628eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian#endif
629eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
630eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* allocate/dup new verts */
631eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   for (i = 0; i < 4; i++) {
632eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      v[i] = dup_vert(stage, header->v[0], i);
633eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
634eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
635eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* new verts */
6362161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[0]->data[pos_slot];
637eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[0] -= radius;
638eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[1] -= radius;
639eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6402161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[1]->data[pos_slot];
641eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[0] += radius;
642eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[1] -= radius;
643eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6442161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[2]->data[pos_slot];
645eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[0] += radius;
646eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[1] += radius;
647eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6482161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell   pos = v[3]->data[pos_slot];
649eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[0] -= radius;
650eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pos[1] += radius;
651eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
652eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* new texcoords */
6533d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   tex = v[0]->data[tex_slot];
654eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ASSIGN_4V(tex, -1, -1, k, 1);
655eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6563d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   tex = v[1]->data[tex_slot];
657eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ASSIGN_4V(tex,  1, -1, k, 1);
658eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6593d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   tex = v[2]->data[tex_slot];
660eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ASSIGN_4V(tex,  1,  1, k, 1);
661eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
6623d5e26ebecd2cce4dd6ad7d479a968e1859e11dfBrian Paul   tex = v[3]->data[tex_slot];
663eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   ASSIGN_4V(tex, -1,  1, k, 1);
664eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
665eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* emit 2 tris for the quad strip */
666eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[0] = v[0];
667eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[1] = v[1];
668eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[2] = v[2];
669eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->next->tri( stage->next, &tri );
670eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
671eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[0] = v[0];
672eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[1] = v[2];
673eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   tri.v[2] = v[3];
674eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->next->tri( stage->next, &tri );
675eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
676eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
677eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
678eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
679eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_first_point(struct draw_stage *stage, struct prim_header *header)
680eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
681eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   auto struct aapoint_stage *aapoint = aapoint_stage(stage);
682eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct draw_context *draw = stage->draw;
683e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
684e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   const struct pipe_rasterizer_state *rast = draw->rasterizer;
685e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   void *r;
686eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
687eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   assert(draw->rasterizer->point_smooth);
688eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
689eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (draw->rasterizer->point_size <= 2.0)
690eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      aapoint->radius = 1.0;
691eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   else
692eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      aapoint->radius = 0.5f * draw->rasterizer->point_size;
693eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
694eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /*
695e55dccd0bfc41dbcf306f864c01758f8e28fc660Brian    * Bind (generate) our fragprog.
696eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    */
697eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   bind_aapoint_fragment_shader(aapoint);
698eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
699e55dccd0bfc41dbcf306f864c01758f8e28fc660Brian   /* update vertex attrib info */
70089d8577fb3036547ef0b47498cc8dc5c77f886e0Zack Rusin   aapoint->pos_slot = draw_current_shader_position_output(draw);
7012161b0fafcdc16703162dd489d2ec1e7114cce4cKeith Whitwell
702e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   /* allocate the extra post-transformed vertex attribute */
703102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   aapoint->tex_slot = draw_alloc_extra_vertex_attrib(draw,
704102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca                                                      TGSI_SEMANTIC_GENERIC,
705102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca                                                      aapoint->fs->generic_attrib);
706102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca   assert(aapoint->tex_slot > 0); /* output[0] is vertex pos */
707e55dccd0bfc41dbcf306f864c01758f8e28fc660Brian
708eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* find psize slot in post-transform vertex */
709eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->psize_slot = -1;
710eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   if (draw->rasterizer->point_size_per_vertex) {
711102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca      const struct tgsi_shader_info *info = draw_get_shader_info(draw);
712eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      uint i;
713102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca      /* find PSIZ vertex output */
714102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca      for (i = 0; i < info->num_outputs; i++) {
715102bf6e2a70f565f03d5e9c4995b29d61c0aa165José Fonseca         if (info->output_semantic_name[i] == TGSI_SEMANTIC_PSIZE) {
716eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            aapoint->psize_slot = i;
717eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian            break;
718eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian         }
719eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian      }
720eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   }
721eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
722e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   draw->suspend_flushing = TRUE;
723e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
724e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   /* Disable triangle culling, stippling, unfilled mode etc. */
725e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   r = draw_get_rasterizer_no_cull(draw, rast->scissor, rast->flatshade);
726e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   pipe->bind_rasterizer_state(pipe, r);
727e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
728e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   draw->suspend_flushing = FALSE;
729e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
7308437f5c763c1a1ac364d71426109c2b095bbcc72Brian Paul   /* now really draw first point */
731eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->point = aapoint_point;
732eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->point(stage, header);
733eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
734eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
735eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
736eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
737eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_flush(struct draw_stage *stage, unsigned flags)
738eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
739eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct draw_context *draw = stage->draw;
740eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint = aapoint_stage(stage);
741e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   struct pipe_context *pipe = draw->pipe;
742eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
743eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->point = aapoint_first_point;
744eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->next->flush( stage->next, flags );
745eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
746eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* restore original frag shader */
74714d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = TRUE;
748edb19707951306447daef43c1ea3cacec5f211fbJosé Fonseca   aapoint->driver_bind_fs_state(pipe, aapoint->fs ? aapoint->fs->driver_fs : NULL);
749e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
750e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   /* restore original rasterizer state */
751e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   if (draw->rast_handle) {
752e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      pipe->bind_rasterizer_state(pipe, draw->rast_handle);
753e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   }
754e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul
75514d1ca8d867d6e44c756cb759f92421107118b2eBrian Paul   draw->suspend_flushing = FALSE;
756eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
757e22e3927b056806e9bbb089734132ad0bcb98df1Brian Paul   draw_remove_extra_vertex_attribs(draw);
758eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
759eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
760eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
761eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
762eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_reset_stipple_counter(struct draw_stage *stage)
763eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
764eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   stage->next->reset_stipple_counter( stage->next );
765eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
766eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
767eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
768eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
769eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_destroy(struct draw_stage *stage)
770eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
7715349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   struct aapoint_stage* aapoint = aapoint_stage(stage);
7725349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   struct pipe_context *pipe = stage->draw->pipe;
7735349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin
774eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   draw_free_temp_verts( stage );
7755349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin
7765349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   /* restore the old entry points */
7775349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->create_fs_state = aapoint->driver_create_fs_state;
7785349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->bind_fs_state = aapoint->driver_bind_fs_state;
7795349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin   pipe->delete_fs_state = aapoint->driver_delete_fs_state;
7805349b95920c82ab9187fe965f3921bd564fe6524Stéphane Marchesin
781eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   FREE( stage );
782eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
783eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
784eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
785eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic struct aapoint_stage *
786eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Briandraw_aapoint_stage(struct draw_context *draw)
787eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
788eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint = CALLOC_STRUCT(aapoint_stage);
7890cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (aapoint == NULL)
7900cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell      goto fail;
791eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
792eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.draw = draw;
793eb979cef8535914f428d2462e78f713da558fc18Keith Whitwell   aapoint->stage.name = "aapoint";
794eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.next = NULL;
795eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.point = aapoint_first_point;
796a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   aapoint->stage.line = draw_pipe_passthrough_line;
797a918a9c744f656c8bf2e3fd2841732e01a5ccefcKeith Whitwell   aapoint->stage.tri = draw_pipe_passthrough_tri;
798eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.flush = aapoint_flush;
799eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.reset_stipple_counter = aapoint_reset_stipple_counter;
800eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->stage.destroy = aapoint_destroy;
801eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
8021c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane   if (!draw_alloc_temp_verts( &aapoint->stage, 4 ))
8031c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      goto fail;
8041c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane
805eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   return aapoint;
8060cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
8070cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell fail:
8080cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (aapoint)
8091c377cea1094c0b5414c663adf2fd393bf41ddfbAlan Hourihane      aapoint->stage.destroy(&aapoint->stage);
8100cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
8110cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   return NULL;
8120cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
813eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
814eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
815eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
816eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic struct aapoint_stage *
817eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_stage_from_pipe(struct pipe_context *pipe)
818eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
81978220aea864c36038f8425ad9d8467d2a2bdea58Brian   struct draw_context *draw = (struct draw_context *) pipe->draw;
82078220aea864c36038f8425ad9d8467d2a2bdea58Brian   return aapoint_stage(draw->pipeline.aapoint);
821eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
822eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
823eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
824eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
825eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * This function overrides the driver's create_fs_state() function and
826eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * will typically be called by the state tracker.
827eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
828eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void *
829eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_create_fs_state(struct pipe_context *pipe,
830eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                       const struct pipe_shader_state *fs)
831eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
832eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
833eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_fragment_shader *aafs = CALLOC_STRUCT(aapoint_fragment_shader);
8340d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   if (aafs == NULL)
8350d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell      return NULL;
836eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
837fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca   aafs->state.tokens = tgsi_dup_tokens(fs->tokens);
838eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
8390d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   /* pass-through */
840e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aafs->driver_fs = aapoint->driver_create_fs_state(pipe, fs);
841eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
842eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   return aafs;
843eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
844eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
845eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
846eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
847eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_bind_fs_state(struct pipe_context *pipe, void *fs)
848eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
849eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
850eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
851eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* save current */
852eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->fs = aafs;
853eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* pass-through */
854e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aapoint->driver_bind_fs_state(pipe,
855339e7ec6805e6de8794514c0a935081b5d36d38fBrian                                 (aafs ? aafs->driver_fs : NULL));
856eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
857eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
858eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
859eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianstatic void
860eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brianaapoint_delete_fs_state(struct pipe_context *pipe, void *fs)
861eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
862eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint = aapoint_stage_from_pipe(pipe);
863eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_fragment_shader *aafs = (struct aapoint_fragment_shader *) fs;
8641aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell
865eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* pass-through */
866e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul   aapoint->driver_delete_fs_state(pipe, aafs->driver_fs);
8671aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell
8681aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell   if (aafs->aapoint_fs)
869e3a34cc7f6c9f959cdc2af4486e84587fab4d0d7Brian Paul      aapoint->driver_delete_fs_state(pipe, aafs->aapoint_fs);
8701aef032d438aaa40ec28bf279ad5c089370773f0Keith Whitwell
871fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca   FREE((void*)aafs->state.tokens);
872fc31f9a3f255c5565ce2a3e9c73415bc17199e28José Fonseca
873eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   FREE(aafs);
874eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
875eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
876eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
877eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian/**
878eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * Called by drivers that want to install this AA point prim stage
879eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * into the draw module's pipeline.  This will not be used if the
880eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian * hardware has native support for AA points.
881eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian */
8820cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwellboolean
883eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Briandraw_install_aapoint_stage(struct draw_context *draw,
884eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian                           struct pipe_context *pipe)
885eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian{
886eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   struct aapoint_stage *aapoint;
887eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
888e6f3e24330926b2ea04c39b5a60b9a20123e5bd4Brian Paul   pipe->draw = (void *) draw;
889e6f3e24330926b2ea04c39b5a60b9a20123e5bd4Brian Paul
890eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /*
891eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    * Create / install AA point drawing / prim stage
892eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian    */
893eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint = draw_aapoint_stage( draw );
8940cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   if (aapoint == NULL)
895d89de9c13fe6cd1f2f1a82d8bc0988d06e629defVinson Lee      return FALSE;
896eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
897eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* save original driver functions */
898eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->driver_create_fs_state = pipe->create_fs_state;
899eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->driver_bind_fs_state = pipe->bind_fs_state;
900eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   aapoint->driver_delete_fs_state = pipe->delete_fs_state;
901eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian
902eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   /* override the driver's functions */
903eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pipe->create_fs_state = aapoint_create_fs_state;
904eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pipe->bind_fs_state = aapoint_bind_fs_state;
905eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian   pipe->delete_fs_state = aapoint_delete_fs_state;
9060cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
9070cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell   draw->pipeline.aapoint = &aapoint->stage;
9080cd90a917d289363a3edb5cfa40c391eb07aa97cKeith Whitwell
9090d4ece4c5a243dc4b684331bad49f220311e5520Keith Whitwell   return TRUE;
910eb4dc2dd5ed62e6ccb55ccc2bc13f6a2f3fc1f76Brian}
911