Merge branch 'gallium-msaa'
[mesa.git] / src / gallium / drivers / i965 / brw_pipe_rast.c
1
2 #include "util/u_memory.h"
3 #include "pipe/p_defines.h"
4 #include "brw_context.h"
5 #include "brw_defines.h"
6 #include "brw_pipe_rast.h"
7 #include "brw_wm.h"
8
9
10 static unsigned translate_fill( unsigned fill )
11 {
12 switch (fill) {
13 case PIPE_POLYGON_MODE_FILL:
14 return CLIP_FILL;
15 case PIPE_POLYGON_MODE_LINE:
16 return CLIP_LINE;
17 case PIPE_POLYGON_MODE_POINT:
18 return CLIP_POINT;
19 default:
20 assert(0);
21 return CLIP_FILL;
22 }
23 }
24
25
26 /* Calculates the key for triangle-mode clipping. Non-triangle
27 * clipping keys use much less information and are computed on the
28 * fly.
29 */
30 static void
31 calculate_clip_key_rast( const struct brw_context *brw,
32 const struct pipe_rasterizer_state *templ,
33 const struct brw_rasterizer_state *rast,
34 struct brw_clip_prog_key *key)
35 {
36 memset(key, 0, sizeof *key);
37
38 if (brw->chipset.is_igdng)
39 key->clip_mode = BRW_CLIPMODE_KERNEL_CLIP;
40 else
41 key->clip_mode = BRW_CLIPMODE_NORMAL;
42
43 key->do_flat_shading = templ->flatshade;
44
45 if (templ->cull_face == PIPE_FACE_FRONT_AND_BACK) {
46 key->clip_mode = BRW_CLIPMODE_REJECT_ALL;
47 return;
48 }
49
50 key->fill_ccw = CLIP_CULL;
51 key->fill_cw = CLIP_CULL;
52
53 if (!(templ->cull_face & PIPE_FACE_FRONT)) {
54 if (templ->front_ccw)
55 key->fill_ccw = translate_fill(templ->fill_front);
56 else
57 key->fill_cw = translate_fill(templ->fill_front);
58 }
59
60 if (!(templ->cull_face & PIPE_FACE_BACK)) {
61 if (templ->front_ccw)
62 key->fill_cw = translate_fill(templ->fill_back);
63 else
64 key->fill_ccw = translate_fill(templ->fill_back);
65 }
66
67 if (key->fill_cw == CLIP_LINE ||
68 key->fill_ccw == CLIP_LINE ||
69 key->fill_cw == CLIP_POINT ||
70 key->fill_ccw == CLIP_POINT) {
71 key->do_unfilled = 1;
72 key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
73 }
74
75 switch (key->fill_cw) {
76 case CLIP_POINT:
77 key->offset_cw = templ->offset_point;
78 break;
79 case CLIP_LINE:
80 key->offset_cw = templ->offset_line;
81 break;
82 case CLIP_FILL:
83 key->offset_cw = templ->offset_tri;
84 break;
85 }
86
87 switch (key->fill_ccw) {
88 case CLIP_POINT:
89 key->offset_ccw = templ->offset_point;
90 break;
91 case CLIP_LINE:
92 key->offset_ccw = templ->offset_line;
93 break;
94 case CLIP_FILL:
95 key->offset_ccw = templ->offset_tri;
96 break;
97 }
98
99 if (templ->light_twoside && key->fill_cw != CLIP_CULL)
100 key->copy_bfc_cw = 1;
101
102 if (templ->light_twoside && key->fill_ccw != CLIP_CULL)
103 key->copy_bfc_ccw = 1;
104 }
105
106
107 static void
108 calculate_line_stipple_rast( const struct pipe_rasterizer_state *templ,
109 struct brw_line_stipple *bls )
110 {
111 GLfloat tmp = 1.0f / (templ->line_stipple_factor + 1);
112 GLint tmpi = tmp * (1<<13);
113
114 bls->header.opcode = CMD_LINE_STIPPLE_PATTERN;
115 bls->header.length = sizeof(*bls)/4 - 2;
116 bls->bits0.pattern = templ->line_stipple_pattern;
117 bls->bits1.repeat_count = templ->line_stipple_factor + 1;
118 bls->bits1.inverse_repeat_count = tmpi;
119 }
120
121 static void *brw_create_rasterizer_state( struct pipe_context *pipe,
122 const struct pipe_rasterizer_state *templ )
123 {
124 struct brw_context *brw = brw_context(pipe);
125 struct brw_rasterizer_state *rast;
126
127 rast = CALLOC_STRUCT(brw_rasterizer_state);
128 if (rast == NULL)
129 return NULL;
130
131 rast->templ = *templ;
132
133 calculate_clip_key_rast( brw, templ, rast, &rast->clip_key );
134
135 if (templ->line_stipple_enable)
136 calculate_line_stipple_rast( templ, &rast->bls );
137
138 /* Caclculate lookup value for WM IZ table.
139 */
140 if (templ->line_smooth) {
141 if (templ->fill_front == PIPE_POLYGON_MODE_LINE &&
142 templ->fill_back == PIPE_POLYGON_MODE_LINE) {
143 rast->unfilled_aa_line = AA_ALWAYS;
144 }
145 else if (templ->fill_front == PIPE_POLYGON_MODE_LINE ||
146 templ->fill_back == PIPE_POLYGON_MODE_LINE) {
147 rast->unfilled_aa_line = AA_SOMETIMES;
148 }
149 else {
150 rast->unfilled_aa_line = AA_NEVER;
151 }
152 }
153 else {
154 rast->unfilled_aa_line = AA_NEVER;
155 }
156
157 return (void *)rast;
158 }
159
160
161 static void brw_bind_rasterizer_state(struct pipe_context *pipe,
162 void *cso)
163 {
164 struct brw_context *brw = brw_context(pipe);
165 brw->curr.rast = (const struct brw_rasterizer_state *)cso;
166 brw->state.dirty.mesa |= PIPE_NEW_RAST;
167 }
168
169 static void brw_delete_rasterizer_state(struct pipe_context *pipe,
170 void *cso)
171 {
172 struct brw_context *brw = brw_context(pipe);
173 assert((const void *)cso != (const void *)brw->curr.rast);
174 FREE(cso);
175 }
176
177
178
179 void brw_pipe_rast_init( struct brw_context *brw )
180 {
181 brw->base.create_rasterizer_state = brw_create_rasterizer_state;
182 brw->base.bind_rasterizer_state = brw_bind_rasterizer_state;
183 brw->base.delete_rasterizer_state = brw_delete_rasterizer_state;
184 }
185
186 void brw_pipe_rast_cleanup( struct brw_context *brw )
187 {
188 }