Merge branch 'mesa_7_7_branch'
[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_mode == PIPE_WINDING_BOTH) {
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_mode & PIPE_WINDING_CCW)) {
54 key->fill_ccw = translate_fill(templ->fill_ccw);
55 }
56
57 if (!(templ->cull_mode & PIPE_WINDING_CW)) {
58 key->fill_cw = translate_fill(templ->fill_cw);
59 }
60
61 if (key->fill_cw == CLIP_LINE ||
62 key->fill_ccw == CLIP_LINE ||
63 key->fill_cw == CLIP_POINT ||
64 key->fill_ccw == CLIP_POINT) {
65 key->do_unfilled = 1;
66 key->clip_mode = BRW_CLIPMODE_CLIP_NON_REJECTED;
67 }
68
69 key->offset_ccw = templ->offset_ccw;
70 key->offset_cw = templ->offset_cw;
71
72 if (templ->light_twoside && key->fill_cw != CLIP_CULL)
73 key->copy_bfc_cw = 1;
74
75 if (templ->light_twoside && key->fill_ccw != CLIP_CULL)
76 key->copy_bfc_ccw = 1;
77 }
78
79
80 static void
81 calculate_line_stipple_rast( const struct pipe_rasterizer_state *templ,
82 struct brw_line_stipple *bls )
83 {
84 GLfloat tmp = 1.0f / (templ->line_stipple_factor + 1);
85 GLint tmpi = tmp * (1<<13);
86
87 bls->header.opcode = CMD_LINE_STIPPLE_PATTERN;
88 bls->header.length = sizeof(*bls)/4 - 2;
89 bls->bits0.pattern = templ->line_stipple_pattern;
90 bls->bits1.repeat_count = templ->line_stipple_factor + 1;
91 bls->bits1.inverse_repeat_count = tmpi;
92 }
93
94 static void *brw_create_rasterizer_state( struct pipe_context *pipe,
95 const struct pipe_rasterizer_state *templ )
96 {
97 struct brw_context *brw = brw_context(pipe);
98 struct brw_rasterizer_state *rast;
99
100 rast = CALLOC_STRUCT(brw_rasterizer_state);
101 if (rast == NULL)
102 return NULL;
103
104 rast->templ = *templ;
105
106 calculate_clip_key_rast( brw, templ, rast, &rast->clip_key );
107
108 if (templ->line_stipple_enable)
109 calculate_line_stipple_rast( templ, &rast->bls );
110
111 /* Caclculate lookup value for WM IZ table.
112 */
113 if (templ->line_smooth) {
114 if (templ->fill_cw == PIPE_POLYGON_MODE_LINE &&
115 templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
116 rast->unfilled_aa_line = AA_ALWAYS;
117 }
118 else if (templ->fill_cw == PIPE_POLYGON_MODE_LINE ||
119 templ->fill_ccw == PIPE_POLYGON_MODE_LINE) {
120 rast->unfilled_aa_line = AA_SOMETIMES;
121 }
122 else {
123 rast->unfilled_aa_line = AA_NEVER;
124 }
125 }
126 else {
127 rast->unfilled_aa_line = AA_NEVER;
128 }
129
130 return (void *)rast;
131 }
132
133
134 static void brw_bind_rasterizer_state(struct pipe_context *pipe,
135 void *cso)
136 {
137 struct brw_context *brw = brw_context(pipe);
138 brw->curr.rast = (const struct brw_rasterizer_state *)cso;
139 brw->state.dirty.mesa |= PIPE_NEW_RAST;
140 }
141
142 static void brw_delete_rasterizer_state(struct pipe_context *pipe,
143 void *cso)
144 {
145 struct brw_context *brw = brw_context(pipe);
146 assert((const void *)cso != (const void *)brw->curr.rast);
147 FREE(cso);
148 }
149
150
151
152 void brw_pipe_rast_init( struct brw_context *brw )
153 {
154 brw->base.create_rasterizer_state = brw_create_rasterizer_state;
155 brw->base.bind_rasterizer_state = brw_bind_rasterizer_state;
156 brw->base.delete_rasterizer_state = brw_delete_rasterizer_state;
157 }
158
159 void brw_pipe_rast_cleanup( struct brw_context *brw )
160 {
161 }