29296c17e9eea869baada9e9cadc553e9f927578
[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 /* BRW_NEW_LOCK */
280 bd.dword2_base_addr = bmBufferOffset(intel, region->buffer);
281
282 bd.dword3.bits.mipmap_layout = BRW_SURFACE_MIPMAPLAYOUT_BELOW;
283 bd.dword3.bits.lod = 0;
284 bd.dword3.bits.width = region->pitch - 1; /* XXX: width ? */
285 bd.dword3.bits.height = region->height - 1;
286
287 bd.dword4.bits.min_array_element = 0;
288 bd.dword4.bits.depth = 0;
289
290 BRW_CACHED_BATCH_STRUCT(brw, &bd);
291 }
292
293 const struct brw_tracked_state brw_depthbuffer = {
294 .dirty = {
295 .mesa = 0,
296 .brw = BRW_NEW_CONTEXT | BRW_NEW_LOCK,
297 .cache = 0
298 },
299 .update = upload_depthbuffer
300 };
301
302
303
304 /***********************************************************************
305 * Polygon stipple packet
306 */
307
308 static void upload_polygon_stipple(struct brw_context *brw)
309 {
310 struct brw_polygon_stipple bps;
311 GLuint i;
312
313 memset(&bps, 0, sizeof(bps));
314 bps.header.opcode = CMD_POLY_STIPPLE_PATTERN;
315 bps.header.length = sizeof(bps)/4-2;
316
317 for (i = 0; i < 32; i++)
318 bps.stipple[i] = brw->attribs.PolygonStipple[31 - i]; /* invert */
319
320 BRW_CACHED_BATCH_STRUCT(brw, &bps);
321 }
322
323 const struct brw_tracked_state brw_polygon_stipple = {
324 .dirty = {
325 .mesa = _NEW_POLYGONSTIPPLE,
326 .brw = 0,
327 .cache = 0
328 },
329 .update = upload_polygon_stipple
330 };
331
332
333 /***********************************************************************
334 * Polygon stipple offset packet
335 */
336
337 static void upload_polygon_stipple_offset(struct brw_context *brw)
338 {
339 __DRIdrawablePrivate *dPriv = brw->intel.driDrawable;
340 struct brw_polygon_stipple_offset bpso;
341
342 memset(&bpso, 0, sizeof(bpso));
343 bpso.header.opcode = CMD_POLY_STIPPLE_OFFSET;
344 bpso.header.length = sizeof(bpso)/4-2;
345
346 bpso.bits0.x_offset = (32 - (dPriv->x & 31)) & 31;
347 bpso.bits0.y_offset = (32 - ((dPriv->y + dPriv->h) & 31)) & 31;
348
349 BRW_CACHED_BATCH_STRUCT(brw, &bpso);
350 }
351
352 const struct brw_tracked_state brw_polygon_stipple_offset = {
353 .dirty = {
354 .mesa = _NEW_WINDOW_POS,
355 .brw = 0,
356 .cache = 0
357 },
358 .update = upload_polygon_stipple_offset
359 };
360
361 /***********************************************************************
362 * Line stipple packet
363 */
364
365 static void upload_line_stipple(struct brw_context *brw)
366 {
367 struct brw_line_stipple bls;
368 GLfloat tmp;
369 GLint tmpi;
370
371 memset(&bls, 0, sizeof(bls));
372 bls.header.opcode = CMD_LINE_STIPPLE_PATTERN;
373 bls.header.length = sizeof(bls)/4 - 2;
374
375 bls.bits0.pattern = brw->attribs.Line->StipplePattern;
376 bls.bits1.repeat_count = brw->attribs.Line->StippleFactor;
377
378 tmp = 1.0 / (GLfloat) brw->attribs.Line->StippleFactor;
379 tmpi = tmp * (1<<13);
380
381
382 bls.bits1.inverse_repeat_count = tmpi;
383
384 BRW_CACHED_BATCH_STRUCT(brw, &bls);
385 }
386
387 const struct brw_tracked_state brw_line_stipple = {
388 .dirty = {
389 .mesa = _NEW_LINE,
390 .brw = 0,
391 .cache = 0
392 },
393 .update = upload_line_stipple
394 };
395
396
397
398 /***********************************************************************
399 * Misc constant state packets
400 */
401
402 static void upload_pipe_control(struct brw_context *brw)
403 {
404 struct brw_pipe_control pc;
405
406 return;
407
408 memset(&pc, 0, sizeof(pc));
409
410 pc.header.opcode = CMD_PIPE_CONTROL;
411 pc.header.length = sizeof(pc)/4 - 2;
412 pc.header.post_sync_operation = PIPE_CONTROL_NOWRITE;
413
414 pc.header.instruction_state_cache_flush_enable = 1;
415
416 pc.bits1.dest_addr_type = PIPE_CONTROL_GTTWRITE_GLOBAL;
417
418 BRW_BATCH_STRUCT(brw, &pc);
419 }
420
421 const struct brw_tracked_state brw_pipe_control = {
422 .dirty = {
423 .mesa = 0,
424 .brw = BRW_NEW_CONTEXT,
425 .cache = 0
426 },
427 .update = upload_pipe_control
428 };
429
430
431 /***********************************************************************
432 * Misc invarient state packets
433 */
434
435 static void upload_invarient_state( struct brw_context *brw )
436 {
437 {
438 /* 0x61040000 Pipeline Select */
439 /* PipelineSelect : 0 */
440 struct brw_pipeline_select ps;
441
442 memset(&ps, 0, sizeof(ps));
443 ps.header.opcode = CMD_PIPELINE_SELECT;
444 ps.header.pipeline_select = 0;
445 BRW_BATCH_STRUCT(brw, &ps);
446 }
447
448 {
449 struct brw_global_depth_offset_clamp gdo;
450 memset(&gdo, 0, sizeof(gdo));
451
452 /* Disable depth offset clamping.
453 */
454 gdo.header.opcode = CMD_GLOBAL_DEPTH_OFFSET_CLAMP;
455 gdo.header.length = sizeof(gdo)/4 - 2;
456 gdo.depth_offset_clamp = 0.0;
457
458 BRW_BATCH_STRUCT(brw, &gdo);
459 }
460
461
462 /* 0x61020000 State Instruction Pointer */
463 {
464 struct brw_system_instruction_pointer sip;
465 memset(&sip, 0, sizeof(sip));
466
467 sip.header.opcode = CMD_STATE_INSN_POINTER;
468 sip.header.length = 0;
469 sip.bits0.pad = 0;
470 sip.bits0.system_instruction_pointer = 0;
471 BRW_BATCH_STRUCT(brw, &sip);
472 }
473
474
475 {
476 struct brw_vf_statistics vfs;
477 memset(&vfs, 0, sizeof(vfs));
478
479 vfs.opcode = CMD_VF_STATISTICS;
480 if (INTEL_DEBUG & DEBUG_STATS)
481 vfs.statistics_enable = 1;
482
483 BRW_BATCH_STRUCT(brw, &vfs);
484 }
485 }
486
487 const struct brw_tracked_state brw_invarient_state = {
488 .dirty = {
489 .mesa = 0,
490 .brw = BRW_NEW_CONTEXT,
491 .cache = 0
492 },
493 .update = upload_invarient_state
494 };
495
496
497 /* State pool addresses:
498 */
499 static void upload_state_base_address( struct brw_context *brw )
500 {
501 struct intel_context *intel = &brw->intel;
502 struct brw_state_base_address sba;
503
504 memset(&sba, 0, sizeof(sba));
505
506 sba.header.opcode = CMD_STATE_BASE_ADDRESS;
507 sba.header.length = 0x4;
508
509 /* BRW_NEW_LOCK */
510 sba.bits0.general_state_address = bmBufferOffset(intel, brw->pool[BRW_GS_POOL].buffer) >> 5;
511 sba.bits0.modify_enable = 1;
512
513 /* BRW_NEW_LOCK */
514 sba.bits1.surface_state_address = bmBufferOffset(intel, brw->pool[BRW_SS_POOL].buffer) >> 5;
515 sba.bits1.modify_enable = 1;
516
517 sba.bits2.modify_enable = 1;
518 sba.bits3.modify_enable = 1;
519 sba.bits4.modify_enable = 1;
520
521 BRW_CACHED_BATCH_STRUCT(brw, &sba);
522 }
523
524
525 const struct brw_tracked_state brw_state_base_address = {
526 .dirty = {
527 .mesa = 0,
528 .brw = BRW_NEW_CONTEXT | BRW_NEW_LOCK,
529 .cache = 0
530 },
531 .update = upload_state_base_address
532 };