1 /**************************************************************************
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * 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, sub license, 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 portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
29 * Keith Whitwell <keith@tungstengraphics.com>
32 #include "i915_state_inlines.h"
33 #include "i915_context.h"
34 #include "i915_state.h"
39 /* All state expressable with the LOAD_STATE_IMMEDIATE_1 packet.
40 * Would like to opportunistically recombine all these fragments into
41 * a single packet containing only what has changed, but for now emit
42 * as multiple packets.
48 /***********************************************************************
49 * S4: Vertex format, rasterization state
51 static void upload_S2S4(struct i915_context
*i915
)
55 /* I915_NEW_VERTEX_FORMAT */
57 LIS2
= i915
->current
.vertex_info
.hwfmt
[1];
58 LIS4
= i915
->current
.vertex_info
.hwfmt
[0];
60 printf("LIS2: 0x%x LIS4: 0x%x\n", LIS2, LIS4);
62 assert(LIS4
); /* should never be zero? */
66 switch (i915
->setup
.cull_mode
) {
67 case PIPE_WINDING_NONE
:
68 LIS4
|= S4_CULLMODE_NONE
;
71 LIS4
|= S4_CULLMODE_CW
;
73 case PIPE_WINDING_CCW
:
74 LIS4
|= S4_CULLMODE_CCW
;
76 case PIPE_WINDING_BOTH
:
77 LIS4
|= S4_CULLMODE_BOTH
;
83 int line_width
= CLAMP((int)(i915
->setup
.line_width
* 2), 1, 0xf);
85 LIS4
|= line_width
<< S4_LINE_WIDTH_SHIFT
;
87 if (i915
->setup
.line_smooth
)
88 LIS4
|= S4_LINE_ANTIALIAS_ENABLE
;
93 int point_size
= CLAMP((int) i915
->setup
.point_size
, 1, 0xff);
95 LIS4
|= point_size
<< S4_POINT_WIDTH_SHIFT
;
99 if (i915
->setup
.flatshade
) {
100 LIS4
|= (S4_FLATSHADE_ALPHA
|
102 S4_FLATSHADE_SPECULAR
);
106 if (LIS2
!= i915
->current
.immediate
[I915_IMMEDIATE_S2
] ||
107 LIS4
!= i915
->current
.immediate
[I915_IMMEDIATE_S4
]) {
109 i915
->current
.immediate
[I915_IMMEDIATE_S2
] = LIS2
;
110 i915
->current
.immediate
[I915_IMMEDIATE_S4
] = LIS4
;
111 i915
->hardware_dirty
|= I915_HW_IMMEDIATE
;
116 const struct i915_tracked_state i915_upload_S2S4
= {
117 .dirty
= I915_NEW_SETUP
| I915_NEW_VERTEX_FORMAT
,
118 .update
= upload_S2S4
123 /***********************************************************************
126 static void upload_S5( struct i915_context
*i915
)
130 /* I915_NEW_STENCIL */
131 if (i915
->depth_stencil
->stencil
.front_enabled
) {
132 int test
= i915_translate_compare_func(i915
->depth_stencil
->stencil
.front_func
);
133 int fop
= i915_translate_stencil_op(i915
->depth_stencil
->stencil
.front_fail_op
);
134 int dfop
= i915_translate_stencil_op(i915
->depth_stencil
->stencil
.front_zfail_op
);
135 int dpop
= i915_translate_stencil_op(i915
->depth_stencil
->stencil
.front_zpass_op
);
136 int ref
= i915
->depth_stencil
->stencil
.ref_value
[0] & 0xff;
138 LIS5
|= (S5_STENCIL_TEST_ENABLE
|
139 S5_STENCIL_WRITE_ENABLE
|
140 (ref
<< S5_STENCIL_REF_SHIFT
) |
141 (test
<< S5_STENCIL_TEST_FUNC_SHIFT
) |
142 (fop
<< S5_STENCIL_FAIL_SHIFT
) |
143 (dfop
<< S5_STENCIL_PASS_Z_FAIL_SHIFT
) |
144 (dpop
<< S5_STENCIL_PASS_Z_PASS_SHIFT
));
148 if (i915
->blend
->logicop_enable
)
149 LIS5
|= S5_LOGICOP_ENABLE
;
151 if (i915
->blend
->dither
)
152 LIS5
|= S5_COLOR_DITHER_ENABLE
;
154 if ((i915
->blend
->colormask
& PIPE_MASK_R
) == 0)
155 LIS5
|= S5_WRITEDISABLE_RED
;
157 if ((i915
->blend
->colormask
& PIPE_MASK_G
) == 0)
158 LIS5
|= S5_WRITEDISABLE_GREEN
;
160 if ((i915
->blend
->colormask
& PIPE_MASK_B
) == 0)
161 LIS5
|= S5_WRITEDISABLE_BLUE
;
163 if ((i915
->blend
->colormask
& PIPE_MASK_A
) == 0)
164 LIS5
|= S5_WRITEDISABLE_ALPHA
;
169 if (i915
->state
.Polygon
->OffsetFill
) {
170 LIS5
|= S5_GLOBAL_DEPTH_OFFSET_ENABLE
;
175 if (LIS5
!= i915
->current
.immediate
[I915_IMMEDIATE_S5
]) {
176 i915
->current
.immediate
[I915_IMMEDIATE_S5
] = LIS5
;
177 i915
->hardware_dirty
|= I915_HW_IMMEDIATE
;
181 const struct i915_tracked_state i915_upload_S5
= {
182 .dirty
= (I915_NEW_DEPTH_STENCIL
| I915_NEW_BLEND
| I915_NEW_SETUP
),
187 /***********************************************************************
189 static void upload_S6( struct i915_context
*i915
)
191 unsigned LIS6
= (S6_COLOR_WRITE_ENABLE
|
192 (2 << S6_TRISTRIP_PV_SHIFT
));
194 /* I915_NEW_ALPHA_TEST
196 if (i915
->alpha_test
.enabled
) {
197 int test
= i915_translate_compare_func(i915
->alpha_test
.func
);
198 ubyte refByte
= float_to_ubyte(i915
->alpha_test
.ref
);
201 LIS6
|= (S6_ALPHA_TEST_ENABLE
|
202 (test
<< S6_ALPHA_TEST_FUNC_SHIFT
) |
203 (((unsigned) refByte
) << S6_ALPHA_REF_SHIFT
));
208 if (i915
->blend
->blend_enable
)
210 unsigned funcRGB
= i915
->blend
->rgb_func
;
211 unsigned srcRGB
= i915
->blend
->rgb_src_factor
;
212 unsigned dstRGB
= i915
->blend
->rgb_dst_factor
;
214 LIS6
|= (S6_CBUF_BLEND_ENABLE
|
215 SRC_BLND_FACT(i915_translate_blend_factor(srcRGB
)) |
216 DST_BLND_FACT(i915_translate_blend_factor(dstRGB
)) |
217 (i915_translate_blend_func(funcRGB
) << S6_CBUF_BLEND_FUNC_SHIFT
));
222 if (i915
->depth_stencil
->depth
.enabled
) {
223 int func
= i915_translate_compare_func(i915
->depth_stencil
->depth
.func
);
225 LIS6
|= (S6_DEPTH_TEST_ENABLE
|
226 (func
<< S6_DEPTH_TEST_FUNC_SHIFT
));
228 if (i915
->depth_stencil
->depth
.writemask
)
229 LIS6
|= S6_DEPTH_WRITE_ENABLE
;
232 if (LIS6
!= i915
->current
.immediate
[I915_IMMEDIATE_S6
]) {
233 i915
->current
.immediate
[I915_IMMEDIATE_S6
] = LIS6
;
234 i915
->hardware_dirty
|= I915_HW_IMMEDIATE
;
238 const struct i915_tracked_state i915_upload_S6
= {
239 .dirty
= I915_NEW_ALPHA_TEST
| I915_NEW_BLEND
| I915_NEW_DEPTH_STENCIL
,
244 /***********************************************************************
246 static void upload_S7( struct i915_context
*i915
)
252 LIS7
= i915
->setup
.offset_units
; /* probably incorrect */
254 if (LIS7
!= i915
->current
.immediate
[I915_IMMEDIATE_S7
]) {
255 i915
->current
.immediate
[I915_IMMEDIATE_S7
] = LIS7
;
256 i915
->hardware_dirty
|= I915_HW_IMMEDIATE
;
260 const struct i915_tracked_state i915_upload_S7
= {
261 .dirty
= I915_NEW_SETUP
,
266 static const struct i915_tracked_state
*atoms
[] = {
275 void i915_update_immediate( struct i915_context
*i915
)
279 for (i
= 0; i
< Elements(atoms
); i
++)
280 if (i915
->dirty
& atoms
[i
]->dirty
)
281 atoms
[i
]->update( i915
);