484913d308c3fb208efae6c5c6e3d58df7f679fb
[mesa.git] / src / mesa / pipe / i915simple / i915_state_immediate.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
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:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
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.
25 *
26 **************************************************************************/
27 /*
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32 #include "i915_state_inlines.h"
33 #include "i915_context.h"
34 #include "i915_state.h"
35 #include "i915_reg.h"
36 #include "p_util.h"
37
38
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.
43 */
44
45
46
47
48 /***********************************************************************
49 * S4: Vertex format, rasterization state
50 */
51 static void upload_S2S4(struct i915_context *i915)
52 {
53 unsigned LIS2, LIS4;
54
55 /* I915_NEW_VERTEX_FORMAT */
56 {
57 LIS2 = i915->current.vertex_info.hwfmt[1];
58 LIS4 = i915->current.vertex_info.hwfmt[0];
59 /*
60 printf("LIS2: 0x%x LIS4: 0x%x\n", LIS2, LIS4);
61 */
62 assert(LIS4); /* should never be zero? */
63 }
64
65 /* I915_NEW_SETUP */
66 switch (i915->setup.cull_mode) {
67 case PIPE_WINDING_NONE:
68 LIS4 |= S4_CULLMODE_NONE;
69 break;
70 case PIPE_WINDING_CW:
71 LIS4 |= S4_CULLMODE_CW;
72 break;
73 case PIPE_WINDING_CCW:
74 LIS4 |= S4_CULLMODE_CCW;
75 break;
76 case PIPE_WINDING_BOTH:
77 LIS4 |= S4_CULLMODE_BOTH;
78 break;
79 }
80
81 /* I915_NEW_SETUP */
82 {
83 int line_width = CLAMP((int)(i915->setup.line_width * 2), 1, 0xf);
84
85 LIS4 |= line_width << S4_LINE_WIDTH_SHIFT;
86
87 if (i915->setup.line_smooth)
88 LIS4 |= S4_LINE_ANTIALIAS_ENABLE;
89 }
90
91 /* I915_NEW_SETUP */
92 {
93 int point_size = CLAMP((int) i915->setup.point_size, 1, 0xff);
94
95 LIS4 |= point_size << S4_POINT_WIDTH_SHIFT;
96 }
97
98 /* I915_NEW_SETUP */
99 if (i915->setup.flatshade) {
100 LIS4 |= (S4_FLATSHADE_ALPHA |
101 S4_FLATSHADE_COLOR |
102 S4_FLATSHADE_SPECULAR);
103 }
104
105
106 if (LIS2 != i915->current.immediate[I915_IMMEDIATE_S2] ||
107 LIS4 != i915->current.immediate[I915_IMMEDIATE_S4]) {
108
109 i915->current.immediate[I915_IMMEDIATE_S2] = LIS2;
110 i915->current.immediate[I915_IMMEDIATE_S4] = LIS4;
111 i915->hardware_dirty |= I915_HW_IMMEDIATE;
112 }
113 }
114
115
116 const struct i915_tracked_state i915_upload_S2S4 = {
117 .dirty = I915_NEW_SETUP | I915_NEW_VERTEX_FORMAT,
118 .update = upload_S2S4
119 };
120
121
122
123 /***********************************************************************
124 *
125 */
126 static void upload_S5( struct i915_context *i915 )
127 {
128 unsigned LIS5 = 0;
129
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;
137
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));
145 }
146
147 /* I915_NEW_BLEND */
148 if (i915->blend->logicop_enable)
149 LIS5 |= S5_LOGICOP_ENABLE;
150
151 if (i915->blend->dither)
152 LIS5 |= S5_COLOR_DITHER_ENABLE;
153
154 if ((i915->blend->colormask & PIPE_MASK_R) == 0)
155 LIS5 |= S5_WRITEDISABLE_RED;
156
157 if ((i915->blend->colormask & PIPE_MASK_G) == 0)
158 LIS5 |= S5_WRITEDISABLE_GREEN;
159
160 if ((i915->blend->colormask & PIPE_MASK_B) == 0)
161 LIS5 |= S5_WRITEDISABLE_BLUE;
162
163 if ((i915->blend->colormask & PIPE_MASK_A) == 0)
164 LIS5 |= S5_WRITEDISABLE_ALPHA;
165
166
167 #if 0
168 /* I915_NEW_SETUP */
169 if (i915->state.Polygon->OffsetFill) {
170 LIS5 |= S5_GLOBAL_DEPTH_OFFSET_ENABLE;
171 }
172 #endif
173
174
175 if (LIS5 != i915->current.immediate[I915_IMMEDIATE_S5]) {
176 i915->current.immediate[I915_IMMEDIATE_S5] = LIS5;
177 i915->hardware_dirty |= I915_HW_IMMEDIATE;
178 }
179 }
180
181 const struct i915_tracked_state i915_upload_S5 = {
182 .dirty = (I915_NEW_DEPTH_STENCIL | I915_NEW_BLEND | I915_NEW_SETUP),
183 .update = upload_S5
184 };
185
186
187 /***********************************************************************
188 */
189 static void upload_S6( struct i915_context *i915 )
190 {
191 unsigned LIS6 = (S6_COLOR_WRITE_ENABLE |
192 (2 << S6_TRISTRIP_PV_SHIFT));
193
194 /* I915_NEW_ALPHA_TEST
195 */
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);
199
200
201 LIS6 |= (S6_ALPHA_TEST_ENABLE |
202 (test << S6_ALPHA_TEST_FUNC_SHIFT) |
203 (((unsigned) refByte) << S6_ALPHA_REF_SHIFT));
204 }
205
206 /* I915_NEW_BLEND
207 */
208 if (i915->blend->blend_enable)
209 {
210 unsigned funcRGB = i915->blend->rgb_func;
211 unsigned srcRGB = i915->blend->rgb_src_factor;
212 unsigned dstRGB = i915->blend->rgb_dst_factor;
213
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));
218 }
219
220 /* I915_NEW_DEPTH
221 */
222 if (i915->depth_stencil->depth.enabled) {
223 int func = i915_translate_compare_func(i915->depth_stencil->depth.func);
224
225 LIS6 |= (S6_DEPTH_TEST_ENABLE |
226 (func << S6_DEPTH_TEST_FUNC_SHIFT));
227
228 if (i915->depth_stencil->depth.writemask)
229 LIS6 |= S6_DEPTH_WRITE_ENABLE;
230 }
231
232 if (LIS6 != i915->current.immediate[I915_IMMEDIATE_S6]) {
233 i915->current.immediate[I915_IMMEDIATE_S6] = LIS6;
234 i915->hardware_dirty |= I915_HW_IMMEDIATE;
235 }
236 }
237
238 const struct i915_tracked_state i915_upload_S6 = {
239 .dirty = I915_NEW_ALPHA_TEST | I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL,
240 .update = upload_S6
241 };
242
243
244 /***********************************************************************
245 */
246 static void upload_S7( struct i915_context *i915 )
247 {
248 float LIS7;
249
250 /* I915_NEW_SETUP
251 */
252 LIS7 = i915->setup.offset_units; /* probably incorrect */
253
254 if (LIS7 != i915->current.immediate[I915_IMMEDIATE_S7]) {
255 i915->current.immediate[I915_IMMEDIATE_S7] = LIS7;
256 i915->hardware_dirty |= I915_HW_IMMEDIATE;
257 }
258 }
259
260 const struct i915_tracked_state i915_upload_S7 = {
261 .dirty = I915_NEW_SETUP,
262 .update = upload_S7
263 };
264
265
266 static const struct i915_tracked_state *atoms[] = {
267 &i915_upload_S2S4,
268 &i915_upload_S5,
269 &i915_upload_S6,
270 &i915_upload_S7
271 };
272
273 /*
274 */
275 void i915_update_immediate( struct i915_context *i915 )
276 {
277 int i;
278
279 for (i = 0; i < Elements(atoms); i++)
280 if (i915->dirty & atoms[i]->dirty)
281 atoms[i]->update( i915 );
282 }