Add Intel i965G/Q DRI driver.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_misc_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
33
34 #include "intel_batchbuffer.h"
35 #include "intel_regions.h"
36
37 #include "brw_context.h"
38 #include "brw_state.h"
39 #include "brw_defines.h"
40
41
42
43
44
45 /***********************************************************************
46 * Blend color
47 */
48
49 static void upload_blend_constant_color(struct brw_context *brw)
50 {
51 struct brw_blend_constant_color bcc;
52
53 memset(&bcc, 0, sizeof(bcc));
54 bcc.header.opcode = CMD_BLEND_CONSTANT_COLOR;
55 bcc.header.length = sizeof(bcc)/4-2;
56 bcc.blend_constant_color[0] = brw->attribs.Color->BlendColor[0];
57 bcc.blend_constant_color[1] = brw->attribs.Color->BlendColor[1];
58 bcc.blend_constant_color[2] = brw->attribs.Color->BlendColor[2];
59 bcc.blend_constant_color[3] = brw->attribs.Color->BlendColor[3];
60
61 BRW_CACHED_BATCH_STRUCT(brw, &bcc);
62 }
63
64
65 const struct brw_tracked_state brw_blend_constant_color = {
66 .dirty = {
67 .mesa = _NEW_COLOR,
68 .brw = 0,
69 .cache = 0
70 },
71 .update = upload_blend_constant_color
72 };
73
74 /***********************************************************************
75 * Drawing rectangle -- Need for AUB file only.
76 */
77
78 static void upload_drawing_rect(struct brw_context *brw)
79 {
80 struct intel_context *intel = &brw->intel;
81 __DRIdrawablePrivate *dPriv = intel->driDrawable;
82 struct brw_drawrect bdr;
83 int x1, y1;
84 int x2, y2;
85
86 if (!brw->intel.aub_file)
87 return;
88
89 /* Basically calculate a single cliprect for the whole window.
90 * Don't bother iterating over cliprects at the moment.
91 */
92
93 x1 = dPriv->x;
94 y1 = dPriv->y;
95 x2 = dPriv->x + dPriv->w;
96 y2 = dPriv->y + dPriv->h;
97
98 if (x1 < 0) x1 = 0;
99 if (y1 < 0) y1 = 0;
100 if (x2 > intel->intelScreen->width) x2 = intel->intelScreen->width;
101 if (y2 > intel->intelScreen->height) y2 = intel->intelScreen->height;
102
103 memset(&bdr, 0, sizeof(bdr));
104 bdr.header.opcode = CMD_DRAW_RECT;
105 bdr.header.length = sizeof(bdr)/4 - 2;
106 bdr.xmin = x1;
107 bdr.ymin = y1;
108 bdr.xmax = x2;
109 bdr.ymax = y2;
110 bdr.xorg = dPriv->x;
111 bdr.yorg = dPriv->y;
112
113 BRW_CACHED_BATCH_STRUCT(brw, &bdr);
114 }
115
116 const struct brw_tracked_state brw_drawing_rect = {
117 .dirty = {
118 .mesa = _NEW_WINDOW_POS,
119 .brw = 0,
120 .cache = 0
121 },
122 .update = upload_drawing_rect
123 };
124
125 /***********************************************************************
126 * Binding table pointers
127 */
128
129 static void upload_binding_table_pointers(struct brw_context *brw)
130 {
131 struct brw_binding_table_pointers btp;
132 memset(&btp, 0, sizeof(btp));
133
134 /* The binding table has been emitted to the SS pool already, so we
135 * know what its offset is. When the batch buffer is fired, the
136 * binding table and surface structs will get fixed up to point to
137 * where the textures actually landed, but that won't change the
138 * value of the offsets here:
139 */
140 btp.header.opcode = CMD_BINDING_TABLE_PTRS;
141 btp.header.length = sizeof(btp)/4 - 2;
142 btp.vs = 0;
143 btp.gs = 0;
144 btp.clp = 0;
145 btp.sf = 0;
146 btp.wm = brw->wm.bind_ss_offset;
147
148 BRW_CACHED_BATCH_STRUCT(brw, &btp);
149 }
150
151 const struct brw_tracked_state brw_binding_table_pointers = {
152 .dirty = {
153 .mesa = 0,
154 .brw = 0,
155 .cache = CACHE_NEW_SURF_BIND
156 },
157 .update = upload_binding_table_pointers
158 };
159
160
161 /***********************************************************************
162 * Pipelined state pointers. This is the key state packet from which
163 * the hardware chases pointers to all the uploaded state in VRAM.
164 */
165
166 static void upload_pipelined_state_pointers(struct brw_context *brw )
167 {
168 struct brw_pipelined_state_pointers psp;
169 memset(&psp, 0, sizeof(psp));
170
171 psp.header.opcode = CMD_PIPELINED_STATE_POINTERS;
172 psp.header.length = sizeof(psp)/4 - 2;
173
174 psp.vs.offset = brw->vs.state_gs_offset >> 5;
175 psp.sf.offset = brw->sf.state_gs_offset >> 5;
176 psp.wm.offset = brw->wm.state_gs_offset >> 5;
177 psp.cc.offset = brw->cc.state_gs_offset >> 5;
178
179 /* GS gets turned on and off regularly. Need to re-emit URB fence
180 * after this occurs.
181 */
182 if (brw->gs.prog_active) {
183 psp.gs.offset = brw->gs.state_gs_offset >> 5;
184 psp.gs.enable = 1;
185 }
186
187 if (!brw->metaops.active) {
188 psp.clp.offset = brw->clip.state_gs_offset >> 5;
189 psp.clp.enable = 1;
190 }
191
192
193 if (BRW_CACHED_BATCH_STRUCT(brw, &psp))
194 brw->state.dirty.brw |= BRW_NEW_PSP;
195 }
196
197 const struct brw_tracked_state brw_pipelined_state_pointers = {
198 .dirty = {
199 .mesa = 0,
200 .brw = BRW_NEW_METAOPS,
201 .cache = (CACHE_NEW_VS_UNIT |
202 CACHE_NEW_GS_UNIT |
203 CACHE_NEW_GS_PROG |
204 CACHE_NEW_CLIP_UNIT |
205 CACHE_NEW_SF_UNIT |
206 CACHE_NEW_WM_UNIT |
207 CACHE_NEW_CC_UNIT)
208 },
209 .update = upload_pipelined_state_pointers
210 };
211
212 static void upload_psp_urb_cbs(struct brw_context *brw )
213 {
214 upload_pipelined_state_pointers(brw);
215 brw_upload_urb_fence(brw);
216 brw_upload_constant_buffer_state(brw);
217 }
218
219
220 const struct brw_tracked_state brw_psp_urb_cbs = {
221 .dirty = {
222 .mesa = 0,
223 .brw = BRW_NEW_URB_FENCE | BRW_NEW_METAOPS,
224 .cache = (CACHE_NEW_VS_UNIT |
225 CACHE_NEW_GS_UNIT |
226 CACHE_NEW_GS_PROG |
227 CACHE_NEW_CLIP_UNIT |
228 CACHE_NEW_SF_UNIT |
229 CACHE_NEW_WM_UNIT |
230 CACHE_NEW_CC_UNIT)
231 },
232 .update = upload_psp_urb_cbs
233 };
234
235
236
237
238 /***********************************************************************
239 * Depthbuffer - currently constant, but rotation would change that.
240 */
241
242 static void upload_depthbuffer(struct brw_context *brw)
243 {
244 /* 0x79050003 Depth Buffer */
245 struct intel_context *intel = &brw->intel;
246 struct intel_region *region = brw->state.depth_region;
247 struct brw_depthbuffer bd;
248 memset(&bd, 0, sizeof(bd));
249
250 bd.header.bits.opcode = CMD_DEPTH_BUFFER;
251 bd.header.bits.length = sizeof(bd)/4-2;
252 bd.dword1.bits.pitch = (region->pitch * region->cpp) - 1;
253
254 switch (region->cpp) {
255 case 2:
256 bd.dword1.bits.format = BRW_DEPTHFORMAT_D16_UNORM;
257 break;
258 case 4:
259 if (intel->depth_buffer_is_float)
260 bd.dword1.bits.format = BRW_DEPTHFORMAT_D32_FLOAT;
261 else
262 bd.dword1.bits.format = BRW_DEPTHFORMAT_D24_UNORM_S8_UINT;
263 break;
264 default:
265 assert(0);
266 return;
267 }
268
269 bd.dword1.bits.depth_offset_disable = 0; /* coordinate offset */
270
271 /* The depthbuffer can only use YMAJOR tiling... This is a bit of
272 * a shame as it clashes with the 2d blitter which only supports
273 * XMAJOR tiling...
274 */
275 bd.dword1.bits.tile_walk = BRW_TILEWALK_YMAJOR;
276 bd.dword1.bits.tiled_surface = intel->depth_region->tiled;
277 bd.dword1.bits.surface_type = BRW_SURFACE_2D;
278
279 bd.dword2_base_addr = bmBufferOffset(intel, region->buffer);
280
281 bd.dword3.bits.mipmap_layout = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
282 bd.dword3.bits.lod = 0;
283 bd.dword3.bits.width = region->pitch - 1; /* XXX: width ? */
284 bd.dword3.bits.height = region->height - 1;
285
286 bd.dword4.bits.min_array_element = 0;
287 bd.dword4.bits.depth = 0;
288
289 BRW_CACHED_BATCH_STRUCT(brw, &bd);
290 }
291
292 const struct brw_tracked_state brw_depthbuffer = {
293 .dirty = {
294 .mesa = 0,
295 .brw = BRW_NEW_CONTEXT | BRW_NEW_FENCE,
296 .cache = 0
297 },
298 .update = upload_depthbuffer
299 };
300
301
302
303 /***********************************************************************
304 * Polygon stipple packet
305 */
306
307 static void upload_polygon_stipple(struct brw_context *brw)
308 {
309 struct brw_polygon_stipple bps;
310 GLuint i;
311
312 memset(&bps, 0, sizeof(bps));
313 bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
314 bps.header.length = sizeof(bps)/4-2;
315
316 for (i = 0; i < 32; i++)
317 bps.stipple[i] = brw->attribs.PolygonStipple[31 - i]; /* invert */
318
319 BRW_CACHED_BATCH_STRUCT(brw, &bps);
320 }
321
322 const struct brw_tracked_state brw_polygon_stipple = {
323 .dirty = {
324 .mesa = _NEW_POLYGONSTIPPLE,
325 .brw = 0,
326 .cache = 0
327 },
328 .update = upload_polygon_stipple
329 };
330
331
332 /***********************************************************************
333 * Polygon stipple offset packet
334 */
335
336 static void upload_polygon_stipple_offset(struct brw_context *brw)
337 {
338 __DRIdrawablePrivate *dPriv = brw->intel.driDrawable;
339 struct brw_polygon_stipple_offset bpso;
340
341 memset(&bpso, 0, sizeof(bpso));
342 bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
343 bpso.header.length = sizeof(bpso)/4-2;
344
345 bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31;
346 bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31;
347
348 BRW_CACHED_BATCH_STRUCT(brw, &bpso);
349 }
350
351 const struct brw_tracked_state brw_polygon_stipple_offset = {
352 .dirty = {
353 .mesa = _NEW_WINDOW_POS,
354 .brw = 0,
355 .cache = 0
356 },
357 .update = upload_polygon_stipple_offset
358 };
359
360 /***********************************************************************
361 * Line stipple packet
362 */
363
364 static void upload_line_stipple(struct brw_context *brw)
365 {
366 struct brw_line_stipple bls;
367 GLfloat tmp;
368 GLint tmpi;
369
370 memset(&bls, 0, sizeof(bls));
371 bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
372 bls.header.length = sizeof(bls)/4 - 2;
373
374 bls.bits0.pattern = brw->attribs.Line->StipplePattern;
375 bls.bits1.repeat_count = brw->attribs.Line->StippleFactor;
376
377 tmp = 1.0 / (GLfloat) brw->attribs.Line->StippleFactor;
378 tmpi = tmp * (1<<13);
379
380
381 bls.bits1.inverse_repeat_count = tmpi;
382
383 BRW_CACHED_BATCH_STRUCT(brw, &bls);
384 }
385
386 const struct brw_tracked_state brw_line_stipple = {
387 .dirty = {
388 .mesa = _NEW_LINE,
389 .brw = 0,
390 .cache = 0
391 },
392 .update = upload_line_stipple
393 };
394
395
396
397 /***********************************************************************
398 * Misc constant state packets
399 */
400
401 static void upload_pipe_control(struct brw_context *brw)
402 {
403 struct brw_pipe_control pc;
404
405 return;
406
407 memset(&pc, 0, sizeof(pc));
408
409 pc.header.opcode = CMD_PIPE_CONTROL;
410 pc.header.length = sizeof(pc)/4 - 2;
411 pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE;
412
413 pc.header.instruction_state_cache_flush_enable = 1;
414
415 pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL;
416
417 BRW_BATCH_STRUCT(brw, &pc);
418 }
419
420 const struct brw_tracked_state brw_pipe_control = {
421 .dirty = {
422 .mesa = 0,
423 .brw = BRW_NEW_CONTEXT,
424 .cache = 0
425 },
426 .update = upload_pipe_control
427 };
428
429
430 /***********************************************************************
431 * Misc invarient state packets
432 */
433
434 static void upload_invarient_state( struct brw_context *brw )
435 {
436 {
437 /* 0x61040000 Pipeline Select */
438 /* PipelineSelect : 0 */
439 struct brw_pipeline_select ps;
440
441 memset(&ps, 0, sizeof(ps));
442 ps.header.opcode = CMD_PIPELINE_SELECT;
443 ps.header.pipeline_select = 0;
444 BRW_BATCH_STRUCT(brw, &ps);
445 }
446
447 {
448 struct brw_global_depth_offset_clamp gdo;
449 memset(&gdo, 0, sizeof(gdo));
450
451 /* Disable depth offset clamping.
452 */
453 gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
454 gdo.header.length = sizeof(gdo)/4 - 2;
455 gdo.depth_offset_clamp = 0.0;
456
457 BRW_BATCH_STRUCT(brw, &gdo);
458 }
459
460
461 /* 0x61020000 State Instruction Pointer */
462 {
463 struct brw_system_instruction_pointer sip;
464 memset(&sip, 0, sizeof(sip));
465
466 sip.header.opcode = CMD_STATE_INSN_POINTER;
467 sip.header.length = 0;
468 sip.bits0.pad = 0;
469 sip.bits0.system_instruction_pointer = 0;
470 BRW_BATCH_STRUCT(brw, &sip);
471 }
472
473
474 {
475 struct brw_vf_statistics vfs;
476 memset(&vfs, 0, sizeof(vfs));
477
478 vfs.opcode = CMD_VF_STATISTICS;
479 if (INTEL_DEBUG & DEBUG_STATS)
480 vfs.statistics_enable = 1;
481
482 BRW_BATCH_STRUCT(brw, &vfs);
483 }
484 }
485
486 const struct brw_tracked_state brw_invarient_state = {
487 .dirty = {
488 .mesa = 0,
489 .brw = BRW_NEW_CONTEXT,
490 .cache = 0
491 },
492 .update = upload_invarient_state
493 };
494
495
496 /* State pool addresses:
497 */
498 static void upload_state_base_address( struct brw_context *brw )
499 {
500 struct intel_context *intel = &brw->intel;
501 struct brw_state_base_address sba;
502
503 memset(&sba, 0, sizeof(sba));
504
505 sba.header.opcode = CMD_STATE_BASE_ADDRESS;
506 sba.header.length = 0x4;
507
508 sba.bits0.general_state_address = bmBufferOffset(intel, brw->pool[BRW_GS_POOL].buffer) >> 5;
509 sba.bits0.modify_enable = 1;
510
511 sba.bits1.surface_state_address = bmBufferOffset(intel, brw->pool[BRW_SS_POOL].buffer) >> 5;
512 sba.bits1.modify_enable = 1;
513
514 sba.bits2.modify_enable = 1;
515 sba.bits3.modify_enable = 1;
516 sba.bits4.modify_enable = 1;
517
518 BRW_CACHED_BATCH_STRUCT(brw, &sba);
519 }
520
521
522 const struct brw_tracked_state brw_state_base_address = {
523 .dirty = {
524 .mesa = 0,
525 .brw = BRW_NEW_CONTEXT | BRW_NEW_FENCE,
526 .cache = 0
527 },
528 .update = upload_state_base_address
529 };