Tizen 2.0 Release
[profile/ivi/osmesa.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->gen == 5)
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 }