Merge branch 'master' into asm-shader-rework-1
[profile/ivi/mesa.git] / src / gallium / auxiliary / draw / draw_pipe.c
1 /**************************************************************************
2  * 
3  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4  * All Rights Reserved.
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the
8  * "Software"), to deal in the Software without restriction, including
9  * without limitation the rights to use, copy, modify, merge, publish,
10  * distribute, sub license, and/or sell copies of the Software, and to
11  * permit persons to whom the Software is furnished to do so, subject to
12  * the following conditions:
13  * 
14  * The above copyright notice and this permission notice (including the
15  * next paragraph) shall be included in all copies or substantial portions
16  * of the Software.
17  * 
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  * 
26  **************************************************************************/
27
28  /*
29   * Authors:
30   *   Keith Whitwell <keith@tungstengraphics.com>
31   */
32
33 #include "draw/draw_private.h"
34 #include "draw/draw_pipe.h"
35
36
37
38 boolean draw_pipeline_init( struct draw_context *draw )
39 {
40    /* create pipeline stages */
41    draw->pipeline.wide_line  = draw_wide_line_stage( draw );
42    draw->pipeline.wide_point = draw_wide_point_stage( draw );
43    draw->pipeline.stipple   = draw_stipple_stage( draw );
44    draw->pipeline.unfilled  = draw_unfilled_stage( draw );
45    draw->pipeline.twoside   = draw_twoside_stage( draw );
46    draw->pipeline.offset    = draw_offset_stage( draw );
47    draw->pipeline.clip      = draw_clip_stage( draw );
48    draw->pipeline.flatshade = draw_flatshade_stage( draw );
49    draw->pipeline.cull      = draw_cull_stage( draw );
50    draw->pipeline.validate  = draw_validate_stage( draw );
51    draw->pipeline.first     = draw->pipeline.validate;
52
53    if (!draw->pipeline.wide_line ||
54        !draw->pipeline.wide_point ||
55        !draw->pipeline.stipple ||
56        !draw->pipeline.unfilled ||
57        !draw->pipeline.twoside ||
58        !draw->pipeline.offset ||
59        !draw->pipeline.clip ||
60        !draw->pipeline.flatshade ||
61        !draw->pipeline.cull ||
62        !draw->pipeline.validate)
63       return FALSE;
64
65    /* these defaults are oriented toward the needs of softpipe */
66    draw->pipeline.wide_point_threshold = 1000000.0; /* infinity */
67    draw->pipeline.wide_line_threshold = 1.0;
68    draw->pipeline.line_stipple = TRUE;
69    draw->pipeline.point_sprite = TRUE;
70
71    return TRUE;
72 }
73
74
75 void draw_pipeline_destroy( struct draw_context *draw )
76 {
77    if (draw->pipeline.wide_line)
78       draw->pipeline.wide_line->destroy( draw->pipeline.wide_line );
79    if (draw->pipeline.wide_point)
80       draw->pipeline.wide_point->destroy( draw->pipeline.wide_point );
81    if (draw->pipeline.stipple)
82       draw->pipeline.stipple->destroy( draw->pipeline.stipple );
83    if (draw->pipeline.unfilled)
84       draw->pipeline.unfilled->destroy( draw->pipeline.unfilled );
85    if (draw->pipeline.twoside)
86       draw->pipeline.twoside->destroy( draw->pipeline.twoside );
87    if (draw->pipeline.offset)
88       draw->pipeline.offset->destroy( draw->pipeline.offset );
89    if (draw->pipeline.clip)
90       draw->pipeline.clip->destroy( draw->pipeline.clip );
91    if (draw->pipeline.flatshade)
92       draw->pipeline.flatshade->destroy( draw->pipeline.flatshade );
93    if (draw->pipeline.cull)
94       draw->pipeline.cull->destroy( draw->pipeline.cull );
95    if (draw->pipeline.validate)
96       draw->pipeline.validate->destroy( draw->pipeline.validate );
97    if (draw->pipeline.aaline)
98       draw->pipeline.aaline->destroy( draw->pipeline.aaline );
99    if (draw->pipeline.aapoint)
100       draw->pipeline.aapoint->destroy( draw->pipeline.aapoint );
101    if (draw->pipeline.pstipple)
102       draw->pipeline.pstipple->destroy( draw->pipeline.pstipple );
103    if (draw->pipeline.rasterize)
104       draw->pipeline.rasterize->destroy( draw->pipeline.rasterize );
105 }
106
107
108
109
110
111
112
113 static void do_point( struct draw_context *draw,
114                       const char *v0 )
115 {
116    struct prim_header prim;
117    
118    prim.flags = 0;
119    prim.pad = 0;
120    prim.v[0] = (struct vertex_header *)v0;
121
122    draw->pipeline.first->point( draw->pipeline.first, &prim );
123 }
124
125
126 static void do_line( struct draw_context *draw,
127                      ushort flags,
128                      const char *v0,
129                      const char *v1 )
130 {
131    struct prim_header prim;
132    
133    prim.flags = flags;
134    prim.pad = 0;
135    prim.v[0] = (struct vertex_header *)v0;
136    prim.v[1] = (struct vertex_header *)v1;
137
138    draw->pipeline.first->line( draw->pipeline.first, &prim );
139 }
140
141
142 static void do_triangle( struct draw_context *draw,
143                          ushort flags,
144                          char *v0,
145                          char *v1,
146                          char *v2 )
147 {
148    struct prim_header prim;
149    
150    prim.v[0] = (struct vertex_header *)v0;
151    prim.v[1] = (struct vertex_header *)v1;
152    prim.v[2] = (struct vertex_header *)v2;
153    prim.flags = flags;
154    prim.pad = 0;
155
156    draw->pipeline.first->tri( draw->pipeline.first, &prim );
157 }
158
159
160
161 #define QUAD(i0,i1,i2,i3)                       \
162    do_triangle( draw,                           \
163                 ( DRAW_PIPE_RESET_STIPPLE |     \
164                   DRAW_PIPE_EDGE_FLAG_0 |       \
165                   DRAW_PIPE_EDGE_FLAG_2 ),      \
166                 verts + stride * elts[i0],      \
167                 verts + stride * elts[i1],      \
168                 verts + stride * elts[i3]);     \
169    do_triangle( draw,                           \
170                 ( DRAW_PIPE_EDGE_FLAG_0 |       \
171                   DRAW_PIPE_EDGE_FLAG_1 ),      \
172                 verts + stride * elts[i1],      \
173                 verts + stride * elts[i2],      \
174                 verts + stride * elts[i3])
175
176 #define TRIANGLE(flags,i0,i1,i2)                                        \
177    do_triangle( draw,                                                   \
178                 elts[i0],  /* flags */                          \
179                 verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK),     \
180                 verts + stride * elts[i1],                              \
181                 verts + stride * elts[i2])
182
183 #define LINE(flags,i0,i1)                                       \
184    do_line( draw,                                               \
185             elts[i0],                                   \
186             verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
187             verts + stride * elts[i1])
188
189 #define POINT(i0)                               \
190    do_point( draw,                              \
191              verts + stride * elts[i0] )
192
193 #define FUNC pipe_run
194 #define ARGS                                    \
195     struct draw_context *draw,                  \
196     unsigned prim,                              \
197     struct vertex_header *vertices,             \
198     unsigned stride,                            \
199     const ushort *elts
200
201 #define LOCAL_VARS                                           \
202    char *verts = (char *)vertices;                           \
203    boolean flatfirst = (draw->rasterizer->flatshade &&       \
204                         draw->rasterizer->flatshade_first);  \
205    unsigned i;                                               \
206    ushort flags
207
208 #define FLUSH
209
210 #include "draw_pt_decompose.h"
211 #undef ARGS
212 #undef LOCAL_VARS
213
214
215
216 /* Code to run the pipeline on a fairly arbitary collection of vertices.
217  *
218  * Vertex headers must be pre-initialized with the
219  * UNDEFINED_VERTEX_ID, this code will cause that id to become
220  * overwritten, so it may have to be reset if there is the intention
221  * to reuse the vertices.
222  *
223  * This code provides a callback to reset the vertex id's which the
224  * draw_vbuf.c code uses when it has to perform a flush.
225  */
226 void draw_pipeline_run( struct draw_context *draw,
227                         unsigned prim,
228                         struct vertex_header *vertices,
229                         unsigned vertex_count,
230                         unsigned stride,
231                         const ushort *elts,
232                         unsigned count )
233 {
234    char *verts = (char *)vertices;
235
236    draw->pipeline.verts = verts;
237    draw->pipeline.vertex_stride = stride;
238    draw->pipeline.vertex_count = vertex_count;
239    
240    pipe_run(draw, prim, vertices, stride, elts, count);
241    
242    draw->pipeline.verts = NULL;
243    draw->pipeline.vertex_count = 0;
244 }
245
246 #define QUAD(i0,i1,i2,i3)                                        \
247    do_triangle( draw,                                            \
248                 ( DRAW_PIPE_RESET_STIPPLE |                      \
249                   DRAW_PIPE_EDGE_FLAG_0 |                        \
250                   DRAW_PIPE_EDGE_FLAG_2 ),                       \
251                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
252                 verts + stride * (i1),                           \
253                 verts + stride * (i3));                          \
254    do_triangle( draw,                                            \
255                 ( DRAW_PIPE_EDGE_FLAG_0 |                        \
256                   DRAW_PIPE_EDGE_FLAG_1 ),                       \
257                 verts + stride * ((i1) & ~DRAW_PIPE_FLAG_MASK),  \
258                 verts + stride * (i2),                           \
259                 verts + stride * (i3))
260
261 #define TRIANGLE(flags,i0,i1,i2)                                 \
262    do_triangle( draw,                                            \
263                 flags,  /* flags */                              \
264                 verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK),  \
265                 verts + stride * (i1),                           \
266                 verts + stride * (i2))
267
268 #define LINE(flags,i0,i1)                                   \
269    do_line( draw,                                           \
270             flags,                                          \
271             verts + stride * ((i0) & ~DRAW_PIPE_FLAG_MASK), \
272             verts + stride * (i1))
273
274 #define POINT(i0)                               \
275    do_point( draw,                              \
276              verts + stride * i0 )
277
278 #define FUNC pipe_run_linear
279 #define ARGS                                    \
280     struct draw_context *draw,                  \
281     unsigned prim,                              \
282     struct vertex_header *vertices,             \
283     unsigned stride
284
285 #define LOCAL_VARS                                           \
286    char *verts = (char *)vertices;                           \
287    boolean flatfirst = (draw->rasterizer->flatshade &&       \
288                         draw->rasterizer->flatshade_first);  \
289    unsigned i;                                               \
290    ushort flags
291
292 #define FLUSH
293
294 #include "draw_pt_decompose.h"
295
296 void draw_pipeline_run_linear( struct draw_context *draw,
297                                unsigned prim,
298                                struct vertex_header *vertices,
299                                unsigned count,
300                                unsigned stride )
301 {
302    char *verts = (char *)vertices;
303    draw->pipeline.verts = verts;
304    draw->pipeline.vertex_stride = stride;
305    draw->pipeline.vertex_count = count;
306
307    pipe_run_linear(draw, prim, vertices, stride, count);
308
309    draw->pipeline.verts = NULL;
310    draw->pipeline.vertex_count = 0;
311 }
312
313
314 void draw_pipeline_flush( struct draw_context *draw, 
315                           unsigned flags )
316 {
317    draw->pipeline.first->flush( draw->pipeline.first, flags );
318    draw->pipeline.first = draw->pipeline.validate;
319 }