Merge commit 'origin/gallium-master-merge'
[mesa.git] / src / gallium / drivers / softpipe / sp_prim_setup.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 * \brief A draw stage that drives our triangle setup routines from
30 * within the draw pipeline. One of two ways to drive setup, the
31 * other being in sp_prim_vbuf.c.
32 *
33 * \author Keith Whitwell <keith@tungstengraphics.com>
34 * \author Brian Paul
35 */
36
37
38 #include "sp_context.h"
39 #include "sp_setup.h"
40 #include "sp_state.h"
41 #include "sp_prim_setup.h"
42 #include "draw/draw_pipe.h"
43 #include "draw/draw_vertex.h"
44 #include "util/u_memory.h"
45
46 /**
47 * Triangle setup info (derived from draw_stage).
48 * Also used for line drawing (taking some liberties).
49 */
50 struct setup_stage {
51 struct draw_stage stage; /**< This must be first (base class) */
52
53 struct setup_context *setup;
54 };
55
56
57
58 /**
59 * Basically a cast wrapper.
60 */
61 static INLINE struct setup_stage *setup_stage( struct draw_stage *stage )
62 {
63 return (struct setup_stage *)stage;
64 }
65
66
67 typedef const float (*cptrf4)[4];
68
69 static void
70 do_tri(struct draw_stage *stage, struct prim_header *prim)
71 {
72 struct setup_stage *setup = setup_stage( stage );
73
74 setup_tri( setup->setup,
75 (cptrf4)prim->v[0]->data,
76 (cptrf4)prim->v[1]->data,
77 (cptrf4)prim->v[2]->data );
78 }
79
80 static void
81 do_line(struct draw_stage *stage, struct prim_header *prim)
82 {
83 struct setup_stage *setup = setup_stage( stage );
84
85 setup_line( setup->setup,
86 (cptrf4)prim->v[0]->data,
87 (cptrf4)prim->v[1]->data );
88 }
89
90 static void
91 do_point(struct draw_stage *stage, struct prim_header *prim)
92 {
93 struct setup_stage *setup = setup_stage( stage );
94
95 setup_point( setup->setup,
96 (cptrf4)prim->v[0]->data );
97 }
98
99
100
101
102 static void setup_begin( struct draw_stage *stage )
103 {
104 struct setup_stage *setup = setup_stage(stage);
105
106 setup_prepare( setup->setup );
107
108 stage->point = do_point;
109 stage->line = do_line;
110 stage->tri = do_tri;
111 }
112
113
114 static void setup_first_point( struct draw_stage *stage,
115 struct prim_header *header )
116 {
117 setup_begin(stage);
118 stage->point( stage, header );
119 }
120
121 static void setup_first_line( struct draw_stage *stage,
122 struct prim_header *header )
123 {
124 setup_begin(stage);
125 stage->line( stage, header );
126 }
127
128
129 static void setup_first_tri( struct draw_stage *stage,
130 struct prim_header *header )
131 {
132 setup_begin(stage);
133 stage->tri( stage, header );
134 }
135
136
137
138 static void setup_flush( struct draw_stage *stage,
139 unsigned flags )
140 {
141 stage->point = setup_first_point;
142 stage->line = setup_first_line;
143 stage->tri = setup_first_tri;
144 }
145
146
147 static void reset_stipple_counter( struct draw_stage *stage )
148 {
149 }
150
151
152 static void render_destroy( struct draw_stage *stage )
153 {
154 struct setup_stage *ssetup = setup_stage(stage);
155 setup_destroy_context(ssetup->setup);
156 FREE( stage );
157 }
158
159
160 /**
161 * Create a new primitive setup/render stage.
162 */
163 struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
164 {
165 struct setup_stage *sstage = CALLOC_STRUCT(setup_stage);
166
167 sstage->setup = setup_create_context(softpipe);
168 sstage->stage.draw = softpipe->draw;
169 sstage->stage.point = setup_first_point;
170 sstage->stage.line = setup_first_line;
171 sstage->stage.tri = setup_first_tri;
172 sstage->stage.flush = setup_flush;
173 sstage->stage.reset_stipple_counter = reset_stipple_counter;
174 sstage->stage.destroy = render_destroy;
175
176 return (struct draw_stage *)sstage;
177 }
178
179 struct setup_context *
180 sp_draw_setup_context( struct draw_stage *stage )
181 {
182 struct setup_stage *ssetup = setup_stage(stage);
183 return ssetup->setup;
184 }
185
186 void
187 sp_draw_flush( struct draw_stage *stage )
188 {
189 stage->flush( stage, 0 );
190 }