Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / gallium / drivers / i965 / brw_sf_state.c
1 /*
2  Copyright (C) Intel Corp.  2006.  All Rights Reserved.
3  Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4  develop this 3D driver.
5  
6  Permission is hereby granted, free of charge, to any person obtaining
7  a 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, sublicense, 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
16  portions of the Software.
17  
18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21  IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
22  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25  
26  **********************************************************************/
27  /*
28   * Authors:
29   *   Keith Whitwell <keith@tungstengraphics.com>
30   */
31    
32 #include "util/u_math.h"
33
34 #include "pipe/p_state.h"
35
36 #include "brw_context.h"
37 #include "brw_state.h"
38 #include "brw_defines.h"
39 #include "brw_debug.h"
40 #include "brw_pipe_rast.h"
41
42 static enum pipe_error upload_sf_vp(struct brw_context *brw)
43 {
44    const struct pipe_viewport_state *vp = &brw->curr.viewport;
45    const struct pipe_scissor_state *scissor = &brw->curr.scissor;
46    struct brw_sf_viewport sfv;
47    enum pipe_error ret;
48
49    memset(&sfv, 0, sizeof(sfv));
50
51    /* PIPE_NEW_VIEWPORT, PIPE_NEW_SCISSOR */
52
53    sfv.viewport.m00 = vp->scale[0];
54    sfv.viewport.m11 = vp->scale[1];
55    sfv.viewport.m22 = vp->scale[2];
56    sfv.viewport.m30 = vp->translate[0];
57    sfv.viewport.m31 = vp->translate[1];
58    sfv.viewport.m32 = vp->translate[2];
59
60    sfv.scissor.xmin = scissor->minx;
61    sfv.scissor.xmax = scissor->maxx - 1; /* ? */
62    sfv.scissor.ymin = scissor->miny;
63    sfv.scissor.ymax = scissor->maxy - 1; /* ? */
64
65    ret = brw_cache_data( &brw->cache, BRW_SF_VP, &sfv, NULL, 0,
66                          &brw->sf.vp_bo );
67    if (ret)
68       return ret;
69
70    return PIPE_OK;
71 }
72
73 const struct brw_tracked_state brw_sf_vp = {
74    .dirty = {
75       .mesa  = (PIPE_NEW_VIEWPORT | 
76                 PIPE_NEW_SCISSOR),
77       .brw   = 0,
78       .cache = 0
79    },
80    .prepare = upload_sf_vp
81 };
82
83 struct brw_sf_unit_key {
84    unsigned int total_grf;
85    unsigned int urb_entry_read_length;
86    unsigned int nr_urb_entries, urb_size, sfsize;
87    
88    unsigned scissor:1;
89    unsigned line_smooth:1;
90    unsigned point_sprite:1;
91    unsigned point_attenuated:1;
92    unsigned front_ccw:1;
93    unsigned cull_face:2;
94    unsigned flatshade_first:1;
95    unsigned gl_rasterization_rules:1;
96    unsigned line_last_pixel_enable:1;
97    float line_width;
98    float point_size;
99 };
100
101 static void
102 sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
103 {
104    const struct pipe_rasterizer_state *rast = &brw->curr.rast->templ;
105    memset(key, 0, sizeof(*key));
106
107    /* CACHE_NEW_SF_PROG */
108    key->total_grf = brw->sf.prog_data->total_grf;
109    key->urb_entry_read_length = brw->sf.prog_data->urb_read_length;
110
111    /* BRW_NEW_URB_FENCE */
112    key->nr_urb_entries = brw->urb.nr_sf_entries;
113    key->urb_size = brw->urb.vsize;
114    key->sfsize = brw->urb.sfsize;
115
116    /* PIPE_NEW_RAST */
117    key->scissor = rast->scissor;
118    key->front_ccw = rast->front_ccw;
119    key->cull_face = rast->cull_face;
120    key->line_smooth = rast->line_smooth;
121    key->line_width = rast->line_width;
122    key->flatshade_first = rast->flatshade_first;
123    key->line_last_pixel_enable = rast->line_last_pixel;
124    key->gl_rasterization_rules = rast->gl_rasterization_rules;
125
126    key->point_sprite = rast->sprite_coord_enable ? 1 : 0;
127    key->point_attenuated = rast->point_size_per_vertex;
128
129    key->point_size = rast->point_size;
130 }
131
132 static enum pipe_error
133 sf_unit_create_from_key(struct brw_context *brw,
134                         struct brw_sf_unit_key *key,
135                         struct brw_winsys_reloc *reloc,
136                         struct brw_winsys_buffer **bo_out)
137 {
138    struct brw_sf_unit_state sf;
139    enum pipe_error ret;
140    int chipset_max_threads;
141    memset(&sf, 0, sizeof(sf));
142
143    sf.thread0.grf_reg_count = align(key->total_grf, 16) / 16 - 1;
144    /* reloc */
145    sf.thread0.kernel_start_pointer = 0;
146
147    sf.thread1.floating_point_mode = BRW_FLOATING_POINT_NON_IEEE_754;
148
149    sf.thread3.dispatch_grf_start_reg = 3;
150
151    if (brw->gen == 5)
152        sf.thread3.urb_entry_read_offset = 3;
153    else
154        sf.thread3.urb_entry_read_offset = 1;
155
156    sf.thread3.urb_entry_read_length = key->urb_entry_read_length;
157
158    sf.thread4.nr_urb_entries = key->nr_urb_entries;
159    sf.thread4.urb_entry_allocation_size = key->sfsize - 1;
160
161    /* Each SF thread produces 1 PUE, and there can be up to 24(Pre-IGDNG) or 
162     * 48(IGDNG) threads 
163     */
164    if (brw->gen == 5)
165       chipset_max_threads = 48;
166    else
167       chipset_max_threads = 24;
168
169    sf.thread4.max_threads = MIN2(chipset_max_threads, key->nr_urb_entries) - 1;
170
171    if (BRW_DEBUG & DEBUG_SINGLE_THREAD)
172       sf.thread4.max_threads = 0;
173
174    if (BRW_DEBUG & DEBUG_STATS)
175       sf.thread4.stats_enable = 1;
176
177    /* CACHE_NEW_SF_VP */
178    /* reloc */
179    sf.sf5.sf_viewport_state_offset = 0;
180
181    sf.sf5.viewport_transform = 1;
182
183    if (key->scissor)
184       sf.sf6.scissor = 1;
185
186    if (key->front_ccw)
187       sf.sf5.front_winding = BRW_FRONTWINDING_CCW;
188    else
189       sf.sf5.front_winding = BRW_FRONTWINDING_CW;
190
191    switch (key->cull_face) {
192    case PIPE_FACE_FRONT:
193       sf.sf6.cull_mode = BRW_CULLMODE_FRONT;
194       break;
195    case PIPE_FACE_BACK:
196       sf.sf6.cull_mode = BRW_CULLMODE_BACK;
197       break;
198    case PIPE_FACE_FRONT_AND_BACK:
199       sf.sf6.cull_mode = BRW_CULLMODE_BOTH;
200       break;
201    case PIPE_FACE_NONE:
202       sf.sf6.cull_mode = BRW_CULLMODE_NONE;
203       break;
204    default:
205       assert(0);
206       sf.sf6.cull_mode = BRW_CULLMODE_NONE;
207       break;
208    }
209
210    /* _NEW_LINE */
211    /* XXX use ctx->Const.Min/MaxLineWidth here */
212    sf.sf6.line_width = CLAMP(key->line_width, 1.0, 5.0) * (1<<1);
213
214    sf.sf6.line_endcap_aa_region_width = 1;
215    if (key->line_smooth)
216       sf.sf6.aa_enable = 1;
217    else if (sf.sf6.line_width <= 0x2)
218        sf.sf6.line_width = 0;
219
220    /* XXX: gl_rasterization_rules?  something else?
221     */
222    sf.sf6.point_rast_rule = BRW_RASTRULE_UPPER_RIGHT;
223    sf.sf6.point_rast_rule = BRW_RASTRULE_LOWER_RIGHT;
224    sf.sf6.point_rast_rule = 1;
225
226    /* XXX clamp max depends on AA vs. non-AA */
227
228    /* _NEW_POINT */
229    sf.sf7.sprite_point = key->point_sprite;
230    sf.sf7.point_size = CLAMP(rint(key->point_size), 1, 255) * (1<<3);
231    sf.sf7.use_point_size_state = !key->point_attenuated;
232    sf.sf7.aa_line_distance_mode = 0;
233
234    /* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
235     */
236    if (!key->flatshade_first) {
237       sf.sf7.trifan_pv = 2;
238       sf.sf7.linestrip_pv = 1;
239       sf.sf7.tristrip_pv = 2;
240    } else {
241       sf.sf7.trifan_pv = 1;
242       sf.sf7.linestrip_pv = 0;
243       sf.sf7.tristrip_pv = 0;
244    }
245
246    sf.sf7.line_last_pixel_enable = key->line_last_pixel_enable;
247
248    /* Set bias for OpenGL rasterization rules:
249     */
250    if (key->gl_rasterization_rules) {
251       sf.sf6.dest_org_vbias = 0x8;
252       sf.sf6.dest_org_hbias = 0x8;
253    }
254    else {
255       sf.sf6.dest_org_vbias = 0x0;
256       sf.sf6.dest_org_hbias = 0x0;
257    }
258
259    ret = brw_upload_cache(&brw->cache, BRW_SF_UNIT,
260                           key, sizeof(*key),
261                           reloc, 2,
262                           &sf, sizeof(sf),
263                           NULL, NULL,
264                           bo_out);
265    if (ret)
266       return ret;
267
268    
269    return PIPE_OK;
270 }
271
272 static enum pipe_error upload_sf_unit( struct brw_context *brw )
273 {
274    struct brw_sf_unit_key key;
275    struct brw_winsys_reloc reloc[2];
276    unsigned total_grf;
277    unsigned viewport_transform;
278    unsigned front_winding;
279    enum pipe_error ret;
280
281    sf_unit_populate_key(brw, &key);
282    
283    /* XXX: cut this crap and pre calculate the key:
284     */
285    total_grf = (align(key.total_grf, 16) / 16 - 1);
286    viewport_transform = 1;
287    front_winding = (key.front_ccw ?
288                     BRW_FRONTWINDING_CCW :
289                     BRW_FRONTWINDING_CW);
290
291    /* Emit SF program relocation */
292    make_reloc(&reloc[0],
293               BRW_USAGE_STATE,
294               total_grf << 1,
295               offsetof(struct brw_sf_unit_state, thread0),
296               brw->sf.prog_bo);
297
298    /* Emit SF viewport relocation */
299    make_reloc(&reloc[1],
300               BRW_USAGE_STATE,
301               front_winding | (viewport_transform << 1),
302               offsetof(struct brw_sf_unit_state, sf5),
303               brw->sf.vp_bo);
304
305
306    if (brw_search_cache(&brw->cache, BRW_SF_UNIT,
307                         &key, sizeof(key),
308                         reloc, 2,
309                         NULL,
310                         &brw->sf.state_bo))
311       return PIPE_OK;
312
313
314    ret = sf_unit_create_from_key(brw, &key,
315                                  reloc,
316                                  &brw->sf.state_bo);
317    if (ret)
318       return ret;
319
320    return PIPE_OK;
321 }
322
323 const struct brw_tracked_state brw_sf_unit = {
324    .dirty = {
325       .mesa  = (PIPE_NEW_RAST),
326       .brw   = BRW_NEW_URB_FENCE,
327       .cache = (CACHE_NEW_SF_VP |
328                 CACHE_NEW_SF_PROG)
329    },
330    .prepare = upload_sf_unit,
331 };