2 Copyright (C) Intel Corp. 2006. All Rights Reserved.
3 Intel funded Tungsten Graphics (http://www.tungstengraphics.com) to
4 develop this 3D driver.
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:
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.
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.
26 **********************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
34 #include "intel_batchbuffer.h"
35 #include "intel_regions.h"
37 #include "brw_context.h"
38 #include "brw_state.h"
39 #include "brw_defines.h"
45 /***********************************************************************
49 static void upload_blend_constant_color(struct brw_context
*brw
)
51 struct brw_blend_constant_color bcc
;
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];
61 BRW_CACHED_BATCH_STRUCT(brw
, &bcc
);
65 const struct brw_tracked_state brw_blend_constant_color
= {
71 .update
= upload_blend_constant_color
74 /***********************************************************************
75 * Drawing rectangle -- Need for AUB file only.
78 static void upload_drawing_rect(struct brw_context
*brw
)
80 struct intel_context
*intel
= &brw
->intel
;
81 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
82 struct brw_drawrect bdr
;
86 if (!brw
->intel
.aub_file
)
89 /* Basically calculate a single cliprect for the whole window.
90 * Don't bother iterating over cliprects at the moment.
95 x2
= dPriv
->x
+ dPriv
->w
;
96 y2
= dPriv
->y
+ dPriv
->h
;
100 if (x2
> intel
->intelScreen
->width
) x2
= intel
->intelScreen
->width
;
101 if (y2
> intel
->intelScreen
->height
) y2
= intel
->intelScreen
->height
;
103 memset(&bdr
, 0, sizeof(bdr
));
104 bdr
.header
.opcode
= CMD_DRAW_RECT
;
105 bdr
.header
.length
= sizeof(bdr
)/4 - 2;
113 BRW_CACHED_BATCH_STRUCT(brw
, &bdr
);
116 const struct brw_tracked_state brw_drawing_rect
= {
118 .mesa
= _NEW_WINDOW_POS
,
122 .update
= upload_drawing_rect
125 /***********************************************************************
126 * Binding table pointers
129 static void upload_binding_table_pointers(struct brw_context
*brw
)
131 struct brw_binding_table_pointers btp
;
132 memset(&btp
, 0, sizeof(btp
));
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:
140 btp
.header
.opcode
= CMD_BINDING_TABLE_PTRS
;
141 btp
.header
.length
= sizeof(btp
)/4 - 2;
146 btp
.wm
= brw
->wm
.bind_ss_offset
;
148 BRW_CACHED_BATCH_STRUCT(brw
, &btp
);
151 const struct brw_tracked_state brw_binding_table_pointers
= {
155 .cache
= CACHE_NEW_SURF_BIND
157 .update
= upload_binding_table_pointers
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.
166 static void upload_pipelined_state_pointers(struct brw_context
*brw
)
168 struct brw_pipelined_state_pointers psp
;
169 memset(&psp
, 0, sizeof(psp
));
171 psp
.header
.opcode
= CMD_PIPELINED_STATE_POINTERS
;
172 psp
.header
.length
= sizeof(psp
)/4 - 2;
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;
179 /* GS gets turned on and off regularly. Need to re-emit URB fence
182 if (brw
->gs
.prog_active
) {
183 psp
.gs
.offset
= brw
->gs
.state_gs_offset
>> 5;
187 if (!brw
->metaops
.active
) {
188 psp
.clp
.offset
= brw
->clip
.state_gs_offset
>> 5;
193 if (BRW_CACHED_BATCH_STRUCT(brw
, &psp
))
194 brw
->state
.dirty
.brw
|= BRW_NEW_PSP
;
197 const struct brw_tracked_state brw_pipelined_state_pointers
= {
200 .brw
= BRW_NEW_METAOPS
,
201 .cache
= (CACHE_NEW_VS_UNIT
|
204 CACHE_NEW_CLIP_UNIT
|
209 .update
= upload_pipelined_state_pointers
212 static void upload_psp_urb_cbs(struct brw_context
*brw
)
214 upload_pipelined_state_pointers(brw
);
215 brw_upload_urb_fence(brw
);
216 brw_upload_constant_buffer_state(brw
);
220 const struct brw_tracked_state brw_psp_urb_cbs
= {
223 .brw
= BRW_NEW_URB_FENCE
| BRW_NEW_METAOPS
,
224 .cache
= (CACHE_NEW_VS_UNIT
|
227 CACHE_NEW_CLIP_UNIT
|
232 .update
= upload_psp_urb_cbs
238 /***********************************************************************
239 * Depthbuffer - currently constant, but rotation would change that.
242 static void upload_depthbuffer(struct brw_context
*brw
)
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
));
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;
254 switch (region
->cpp
) {
256 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D16_UNORM
;
259 if (intel
->depth_buffer_is_float
)
260 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D32_FLOAT
;
262 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D24_UNORM_S8_UINT
;
269 bd
.dword1
.bits
.depth_offset_disable
= 0; /* coordinate offset */
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
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
;
279 bd
.dword2_base_addr
= bmBufferOffset(intel
, region
->buffer
);
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;
286 bd
.dword4
.bits
.min_array_element
= 0;
287 bd
.dword4
.bits
.depth
= 0;
289 BRW_CACHED_BATCH_STRUCT(brw
, &bd
);
292 const struct brw_tracked_state brw_depthbuffer
= {
295 .brw
= BRW_NEW_CONTEXT
| BRW_NEW_FENCE
,
298 .update
= upload_depthbuffer
303 /***********************************************************************
304 * Polygon stipple packet
307 static void upload_polygon_stipple(struct brw_context
*brw
)
309 struct brw_polygon_stipple bps
;
312 memset(&bps
, 0, sizeof(bps
));
313 bps
.header
.opcode
= CMD_POLY_STIPPLE_PATTERN
;
314 bps
.header
.length
= sizeof(bps
)/4-2;
316 for (i
= 0; i
< 32; i
++)
317 bps
.stipple
[i
] = brw
->attribs
.PolygonStipple
[31 - i
]; /* invert */
319 BRW_CACHED_BATCH_STRUCT(brw
, &bps
);
322 const struct brw_tracked_state brw_polygon_stipple
= {
324 .mesa
= _NEW_POLYGONSTIPPLE
,
328 .update
= upload_polygon_stipple
332 /***********************************************************************
333 * Polygon stipple offset packet
336 static void upload_polygon_stipple_offset(struct brw_context
*brw
)
338 __DRIdrawablePrivate
*dPriv
= brw
->intel
.driDrawable
;
339 struct brw_polygon_stipple_offset bpso
;
341 memset(&bpso
, 0, sizeof(bpso
));
342 bpso
.header
.opcode
= CMD_POLY_STIPPLE_OFFSET
;
343 bpso
.header
.length
= sizeof(bpso
)/4-2;
345 bpso
.bits0
.x_offset
= (32 - (dPriv
->x
& 31)) & 31;
346 bpso
.bits0
.y_offset
= (32 - ((dPriv
->y
+ dPriv
->h
) & 31)) & 31;
348 BRW_CACHED_BATCH_STRUCT(brw
, &bpso
);
351 const struct brw_tracked_state brw_polygon_stipple_offset
= {
353 .mesa
= _NEW_WINDOW_POS
,
357 .update
= upload_polygon_stipple_offset
360 /***********************************************************************
361 * Line stipple packet
364 static void upload_line_stipple(struct brw_context
*brw
)
366 struct brw_line_stipple bls
;
370 memset(&bls
, 0, sizeof(bls
));
371 bls
.header
.opcode
= CMD_LINE_STIPPLE_PATTERN
;
372 bls
.header
.length
= sizeof(bls
)/4 - 2;
374 bls
.bits0
.pattern
= brw
->attribs
.Line
->StipplePattern
;
375 bls
.bits1
.repeat_count
= brw
->attribs
.Line
->StippleFactor
;
377 tmp
= 1.0 / (GLfloat
) brw
->attribs
.Line
->StippleFactor
;
378 tmpi
= tmp
* (1<<13);
381 bls
.bits1
.inverse_repeat_count
= tmpi
;
383 BRW_CACHED_BATCH_STRUCT(brw
, &bls
);
386 const struct brw_tracked_state brw_line_stipple
= {
392 .update
= upload_line_stipple
397 /***********************************************************************
398 * Misc constant state packets
401 static void upload_pipe_control(struct brw_context
*brw
)
403 struct brw_pipe_control pc
;
407 memset(&pc
, 0, sizeof(pc
));
409 pc
.header
.opcode
= CMD_PIPE_CONTROL
;
410 pc
.header
.length
= sizeof(pc
)/4 - 2;
411 pc
.header
.post_sync_operation
= PIPE_CONTROL_NOWRITE
;
413 pc
.header
.instruction_state_cache_flush_enable
= 1;
415 pc
.bits1
.dest_addr_type
= PIPE_CONTROL_GTTWRITE_GLOBAL
;
417 BRW_BATCH_STRUCT(brw
, &pc
);
420 const struct brw_tracked_state brw_pipe_control
= {
423 .brw
= BRW_NEW_CONTEXT
,
426 .update
= upload_pipe_control
430 /***********************************************************************
431 * Misc invarient state packets
434 static void upload_invarient_state( struct brw_context
*brw
)
437 /* 0x61040000 Pipeline Select */
438 /* PipelineSelect : 0 */
439 struct brw_pipeline_select ps
;
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
);
448 struct brw_global_depth_offset_clamp gdo
;
449 memset(&gdo
, 0, sizeof(gdo
));
451 /* Disable depth offset clamping.
453 gdo
.header
.opcode
= CMD_GLOBAL_DEPTH_OFFSET_CLAMP
;
454 gdo
.header
.length
= sizeof(gdo
)/4 - 2;
455 gdo
.depth_offset_clamp
= 0.0;
457 BRW_BATCH_STRUCT(brw
, &gdo
);
461 /* 0x61020000 State Instruction Pointer */
463 struct brw_system_instruction_pointer sip
;
464 memset(&sip
, 0, sizeof(sip
));
466 sip
.header
.opcode
= CMD_STATE_INSN_POINTER
;
467 sip
.header
.length
= 0;
469 sip
.bits0
.system_instruction_pointer
= 0;
470 BRW_BATCH_STRUCT(brw
, &sip
);
475 struct brw_vf_statistics vfs
;
476 memset(&vfs
, 0, sizeof(vfs
));
478 vfs
.opcode
= CMD_VF_STATISTICS
;
479 if (INTEL_DEBUG
& DEBUG_STATS
)
480 vfs
.statistics_enable
= 1;
482 BRW_BATCH_STRUCT(brw
, &vfs
);
486 const struct brw_tracked_state brw_invarient_state
= {
489 .brw
= BRW_NEW_CONTEXT
,
492 .update
= upload_invarient_state
496 /* State pool addresses:
498 static void upload_state_base_address( struct brw_context
*brw
)
500 struct intel_context
*intel
= &brw
->intel
;
501 struct brw_state_base_address sba
;
503 memset(&sba
, 0, sizeof(sba
));
505 sba
.header
.opcode
= CMD_STATE_BASE_ADDRESS
;
506 sba
.header
.length
= 0x4;
508 sba
.bits0
.general_state_address
= bmBufferOffset(intel
, brw
->pool
[BRW_GS_POOL
].buffer
) >> 5;
509 sba
.bits0
.modify_enable
= 1;
511 sba
.bits1
.surface_state_address
= bmBufferOffset(intel
, brw
->pool
[BRW_SS_POOL
].buffer
) >> 5;
512 sba
.bits1
.modify_enable
= 1;
514 sba
.bits2
.modify_enable
= 1;
515 sba
.bits3
.modify_enable
= 1;
516 sba
.bits4
.modify_enable
= 1;
518 BRW_CACHED_BATCH_STRUCT(brw
, &sba
);
522 const struct brw_tracked_state brw_state_base_address
= {
525 .brw
= BRW_NEW_CONTEXT
| BRW_NEW_FENCE
,
528 .update
= upload_state_base_address