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.
77 static void upload_drawing_rect(struct brw_context
*brw
)
79 struct intel_context
*intel
= &brw
->intel
;
80 __DRIdrawablePrivate
*dPriv
= intel
->driDrawable
;
81 struct brw_drawrect bdr
;
85 /* If there is a single cliprect, set it here. Otherwise iterate
86 * over them in brw_draw_prim().
88 if (brw
->intel
.numClipRects
> 1)
91 x1
= brw
->intel
.pClipRects
[0].x1
;
92 y1
= brw
->intel
.pClipRects
[0].y1
;
93 x2
= brw
->intel
.pClipRects
[0].x2
;
94 y2
= brw
->intel
.pClipRects
[0].y2
;
98 if (x2
> intel
->intelScreen
->width
) x2
= intel
->intelScreen
->width
;
99 if (y2
> intel
->intelScreen
->height
) y2
= intel
->intelScreen
->height
;
101 memset(&bdr
, 0, sizeof(bdr
));
102 bdr
.header
.opcode
= CMD_DRAW_RECT
;
103 bdr
.header
.length
= sizeof(bdr
)/4 - 2;
111 /* Can't use BRW_CACHED_BATCH_STRUCT because this is also emitted
112 * uncached in brw_draw.c:
114 BRW_BATCH_STRUCT(brw
, &bdr
);
117 const struct brw_tracked_state brw_drawing_rect
= {
119 .mesa
= _NEW_WINDOW_POS
,
123 .update
= upload_drawing_rect
126 /***********************************************************************
127 * Binding table pointers
130 static void upload_binding_table_pointers(struct brw_context
*brw
)
132 struct brw_binding_table_pointers btp
;
133 memset(&btp
, 0, sizeof(btp
));
135 /* The binding table has been emitted to the SS pool already, so we
136 * know what its offset is. When the batch buffer is fired, the
137 * binding table and surface structs will get fixed up to point to
138 * where the textures actually landed, but that won't change the
139 * value of the offsets here:
141 btp
.header
.opcode
= CMD_BINDING_TABLE_PTRS
;
142 btp
.header
.length
= sizeof(btp
)/4 - 2;
147 btp
.wm
= brw
->wm
.bind_ss_offset
;
149 BRW_CACHED_BATCH_STRUCT(brw
, &btp
);
152 const struct brw_tracked_state brw_binding_table_pointers
= {
156 .cache
= CACHE_NEW_SURF_BIND
158 .update
= upload_binding_table_pointers
162 /***********************************************************************
163 * Pipelined state pointers. This is the key state packet from which
164 * the hardware chases pointers to all the uploaded state in VRAM.
167 static void upload_pipelined_state_pointers(struct brw_context
*brw
)
169 struct brw_pipelined_state_pointers psp
;
170 memset(&psp
, 0, sizeof(psp
));
172 psp
.header
.opcode
= CMD_PIPELINED_STATE_POINTERS
;
173 psp
.header
.length
= sizeof(psp
)/4 - 2;
175 psp
.vs
.offset
= brw
->vs
.state_gs_offset
>> 5;
176 psp
.sf
.offset
= brw
->sf
.state_gs_offset
>> 5;
177 psp
.wm
.offset
= brw
->wm
.state_gs_offset
>> 5;
178 psp
.cc
.offset
= brw
->cc
.state_gs_offset
>> 5;
180 /* GS gets turned on and off regularly. Need to re-emit URB fence
183 if (brw
->gs
.prog_active
) {
184 psp
.gs
.offset
= brw
->gs
.state_gs_offset
>> 5;
188 if (!brw
->metaops
.active
) {
189 psp
.clp
.offset
= brw
->clip
.state_gs_offset
>> 5;
194 if (BRW_CACHED_BATCH_STRUCT(brw
, &psp
))
195 brw
->state
.dirty
.brw
|= BRW_NEW_PSP
;
198 const struct brw_tracked_state brw_pipelined_state_pointers
= {
201 .brw
= BRW_NEW_METAOPS
,
202 .cache
= (CACHE_NEW_VS_UNIT
|
205 CACHE_NEW_CLIP_UNIT
|
210 .update
= upload_pipelined_state_pointers
213 static void upload_psp_urb_cbs(struct brw_context
*brw
)
215 upload_pipelined_state_pointers(brw
);
216 brw_upload_urb_fence(brw
);
217 brw_upload_constant_buffer_state(brw
);
221 const struct brw_tracked_state brw_psp_urb_cbs
= {
224 .brw
= BRW_NEW_URB_FENCE
| BRW_NEW_METAOPS
,
225 .cache
= (CACHE_NEW_VS_UNIT
|
228 CACHE_NEW_CLIP_UNIT
|
233 .update
= upload_psp_urb_cbs
239 /***********************************************************************
240 * Depthbuffer - currently constant, but rotation would change that.
243 static void upload_depthbuffer(struct brw_context
*brw
)
245 /* 0x79050003 Depth Buffer */
246 struct intel_context
*intel
= &brw
->intel
;
247 struct intel_region
*region
= brw
->state
.depth_region
;
248 struct brw_depthbuffer bd
;
249 memset(&bd
, 0, sizeof(bd
));
251 bd
.header
.bits
.opcode
= CMD_DEPTH_BUFFER
;
252 bd
.header
.bits
.length
= sizeof(bd
)/4-2;
253 bd
.dword1
.bits
.pitch
= (region
->pitch
* region
->cpp
) - 1;
255 switch (region
->cpp
) {
257 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D16_UNORM
;
260 if (intel
->depth_buffer_is_float
)
261 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D32_FLOAT
;
263 bd
.dword1
.bits
.format
= BRW_DEPTHFORMAT_D24_UNORM_S8_UINT
;
270 bd
.dword1
.bits
.depth_offset_disable
= 0; /* coordinate offset */
272 /* The depthbuffer can only use YMAJOR tiling... This is a bit of
273 * a shame as it clashes with the 2d blitter which only supports
276 bd
.dword1
.bits
.tile_walk
= BRW_TILEWALK_YMAJOR
;
277 bd
.dword1
.bits
.tiled_surface
= intel
->depth_region
->tiled
;
278 bd
.dword1
.bits
.surface_type
= BRW_SURFACE_2D
;
281 bd
.dword2_base_addr
= bmBufferOffset(intel
, region
->buffer
);
283 bd
.dword3
.bits
.mipmap_layout
= BRW_SURFACE_MIPMAPLAYOUT_BELOW
;
284 bd
.dword3
.bits
.lod
= 0;
285 bd
.dword3
.bits
.width
= region
->pitch
- 1; /* XXX: width ? */
286 bd
.dword3
.bits
.height
= region
->height
- 1;
288 bd
.dword4
.bits
.min_array_element
= 0;
289 bd
.dword4
.bits
.depth
= 0;
291 BRW_CACHED_BATCH_STRUCT(brw
, &bd
);
294 const struct brw_tracked_state brw_depthbuffer
= {
297 .brw
= BRW_NEW_CONTEXT
| BRW_NEW_LOCK
,
300 .update
= upload_depthbuffer
305 /***********************************************************************
306 * Polygon stipple packet
309 static void upload_polygon_stipple(struct brw_context
*brw
)
311 struct brw_polygon_stipple bps
;
314 memset(&bps
, 0, sizeof(bps
));
315 bps
.header
.opcode
= CMD_POLY_STIPPLE_PATTERN
;
316 bps
.header
.length
= sizeof(bps
)/4-2;
318 for (i
= 0; i
< 32; i
++)
319 bps
.stipple
[i
] = brw
->attribs
.PolygonStipple
[31 - i
]; /* invert */
321 BRW_CACHED_BATCH_STRUCT(brw
, &bps
);
324 const struct brw_tracked_state brw_polygon_stipple
= {
326 .mesa
= _NEW_POLYGONSTIPPLE
,
330 .update
= upload_polygon_stipple
334 /***********************************************************************
335 * Polygon stipple offset packet
338 static void upload_polygon_stipple_offset(struct brw_context
*brw
)
340 __DRIdrawablePrivate
*dPriv
= brw
->intel
.driDrawable
;
341 struct brw_polygon_stipple_offset bpso
;
343 memset(&bpso
, 0, sizeof(bpso
));
344 bpso
.header
.opcode
= CMD_POLY_STIPPLE_OFFSET
;
345 bpso
.header
.length
= sizeof(bpso
)/4-2;
347 bpso
.bits0
.x_offset
= (32 - (dPriv
->x
& 31)) & 31;
348 bpso
.bits0
.y_offset
= (32 - ((dPriv
->y
+ dPriv
->h
) & 31)) & 31;
350 BRW_CACHED_BATCH_STRUCT(brw
, &bpso
);
353 const struct brw_tracked_state brw_polygon_stipple_offset
= {
355 .mesa
= _NEW_WINDOW_POS
,
359 .update
= upload_polygon_stipple_offset
362 /***********************************************************************
363 * Line stipple packet
366 static void upload_line_stipple(struct brw_context
*brw
)
368 struct brw_line_stipple bls
;
372 memset(&bls
, 0, sizeof(bls
));
373 bls
.header
.opcode
= CMD_LINE_STIPPLE_PATTERN
;
374 bls
.header
.length
= sizeof(bls
)/4 - 2;
376 bls
.bits0
.pattern
= brw
->attribs
.Line
->StipplePattern
;
377 bls
.bits1
.repeat_count
= brw
->attribs
.Line
->StippleFactor
;
379 tmp
= 1.0 / (GLfloat
) brw
->attribs
.Line
->StippleFactor
;
380 tmpi
= tmp
* (1<<13);
383 bls
.bits1
.inverse_repeat_count
= tmpi
;
385 BRW_CACHED_BATCH_STRUCT(brw
, &bls
);
388 const struct brw_tracked_state brw_line_stipple
= {
394 .update
= upload_line_stipple
399 /***********************************************************************
400 * Misc constant state packets
403 static void upload_pipe_control(struct brw_context
*brw
)
405 struct brw_pipe_control pc
;
409 memset(&pc
, 0, sizeof(pc
));
411 pc
.header
.opcode
= CMD_PIPE_CONTROL
;
412 pc
.header
.length
= sizeof(pc
)/4 - 2;
413 pc
.header
.post_sync_operation
= PIPE_CONTROL_NOWRITE
;
415 pc
.header
.instruction_state_cache_flush_enable
= 1;
417 pc
.bits1
.dest_addr_type
= PIPE_CONTROL_GTTWRITE_GLOBAL
;
419 BRW_BATCH_STRUCT(brw
, &pc
);
422 const struct brw_tracked_state brw_pipe_control
= {
425 .brw
= BRW_NEW_CONTEXT
,
428 .update
= upload_pipe_control
432 /***********************************************************************
433 * Misc invarient state packets
436 static void upload_invarient_state( struct brw_context
*brw
)
439 /* 0x61040000 Pipeline Select */
440 /* PipelineSelect : 0 */
441 struct brw_pipeline_select ps
;
443 memset(&ps
, 0, sizeof(ps
));
444 ps
.header
.opcode
= CMD_PIPELINE_SELECT
;
445 ps
.header
.pipeline_select
= 0;
446 BRW_BATCH_STRUCT(brw
, &ps
);
450 struct brw_global_depth_offset_clamp gdo
;
451 memset(&gdo
, 0, sizeof(gdo
));
453 /* Disable depth offset clamping.
455 gdo
.header
.opcode
= CMD_GLOBAL_DEPTH_OFFSET_CLAMP
;
456 gdo
.header
.length
= sizeof(gdo
)/4 - 2;
457 gdo
.depth_offset_clamp
= 0.0;
459 BRW_BATCH_STRUCT(brw
, &gdo
);
463 /* 0x61020000 State Instruction Pointer */
465 struct brw_system_instruction_pointer sip
;
466 memset(&sip
, 0, sizeof(sip
));
468 sip
.header
.opcode
= CMD_STATE_INSN_POINTER
;
469 sip
.header
.length
= 0;
471 sip
.bits0
.system_instruction_pointer
= 0;
472 BRW_BATCH_STRUCT(brw
, &sip
);
477 struct brw_vf_statistics vfs
;
478 memset(&vfs
, 0, sizeof(vfs
));
480 vfs
.opcode
= CMD_VF_STATISTICS
;
481 if (INTEL_DEBUG
& DEBUG_STATS
)
482 vfs
.statistics_enable
= 1;
484 BRW_BATCH_STRUCT(brw
, &vfs
);
488 const struct brw_tracked_state brw_invarient_state
= {
491 .brw
= BRW_NEW_CONTEXT
,
494 .update
= upload_invarient_state
498 /* State pool addresses:
500 static void upload_state_base_address( struct brw_context
*brw
)
502 struct intel_context
*intel
= &brw
->intel
;
503 struct brw_state_base_address sba
;
505 memset(&sba
, 0, sizeof(sba
));
507 sba
.header
.opcode
= CMD_STATE_BASE_ADDRESS
;
508 sba
.header
.length
= 0x4;
511 sba
.bits0
.general_state_address
= bmBufferOffset(intel
, brw
->pool
[BRW_GS_POOL
].buffer
) >> 5;
512 sba
.bits0
.modify_enable
= 1;
515 sba
.bits1
.surface_state_address
= bmBufferOffset(intel
, brw
->pool
[BRW_SS_POOL
].buffer
) >> 5;
516 sba
.bits1
.modify_enable
= 1;
518 sba
.bits2
.modify_enable
= 1;
519 sba
.bits3
.modify_enable
= 1;
520 sba
.bits4
.modify_enable
= 1;
522 BRW_CACHED_BATCH_STRUCT(brw
, &sba
);
526 const struct brw_tracked_state brw_state_base_address
= {
529 .brw
= BRW_NEW_CONTEXT
| BRW_NEW_LOCK
,
532 .update
= upload_state_base_address