i915g: Rework debug print code
[mesa.git] / src / gallium / drivers / i915 / i915_state_dynamic.c
1 /**************************************************************************
2 *
3 * Copyright 2003 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 #include "i915_batch.h"
29 #include "i915_state_inlines.h"
30 #include "i915_context.h"
31 #include "i915_reg.h"
32 #include "i915_state.h"
33 #include "util/u_math.h"
34 #include "util/u_memory.h"
35 #include "util/u_pack_color.h"
36
37
38 /* State that we have chosen to store in the DYNAMIC segment of the
39 * i915 indirect state mechanism.
40 *
41 * Can't cache these in the way we do the static state, as there is no
42 * start/size in the command packet, instead an 'end' value that gets
43 * incremented.
44 *
45 * Additionally, there seems to be a requirement to re-issue the full
46 * (active) state every time a 4kb boundary is crossed.
47 */
48
49 static INLINE void set_dynamic_indirect(struct i915_context *i915,
50 unsigned offset,
51 const unsigned *src,
52 unsigned dwords)
53 {
54 unsigned i;
55
56 for (i = 0; i < dwords; i++)
57 i915->current.dynamic[offset + i] = src[i];
58
59 i915->hardware_dirty |= I915_HW_DYNAMIC;
60 }
61
62
63
64 /***********************************************************************
65 * Modes4: stencil masks and logicop
66 */
67 static void upload_MODES4(struct i915_context *i915)
68 {
69 unsigned modes4 = 0;
70
71 /* I915_NEW_STENCIL
72 */
73 modes4 |= i915->depth_stencil->stencil_modes4;
74
75 /* I915_NEW_BLEND
76 */
77 modes4 |= i915->blend->modes4;
78
79 /* Always, so that we know when state is in-active:
80 */
81 set_dynamic_indirect(i915,
82 I915_DYNAMIC_MODES4,
83 &modes4,
84 1);
85 }
86
87 const struct i915_tracked_state i915_upload_MODES4 = {
88 "MODES4",
89 upload_MODES4,
90 I915_NEW_BLEND | I915_NEW_DEPTH_STENCIL
91 };
92
93
94
95 /***********************************************************************
96 */
97 static void upload_BFO(struct i915_context *i915)
98 {
99 unsigned bfo[2];
100 bfo[0] = i915->depth_stencil->bfo[0];
101 bfo[1] = i915->depth_stencil->bfo[1];
102 /* I don't get it only allowed to set a ref mask when the enable bit is set? */
103 if (bfo[0] & BFO_ENABLE_STENCIL_REF) {
104 bfo[0] |= i915->stencil_ref.ref_value[1] << BFO_STENCIL_REF_SHIFT;
105 }
106
107 set_dynamic_indirect(i915,
108 I915_DYNAMIC_BFO_0,
109 &(bfo[0]),
110 2);
111 }
112
113 const struct i915_tracked_state i915_upload_BFO = {
114 "BFO",
115 upload_BFO,
116 I915_NEW_DEPTH_STENCIL
117 };
118
119
120
121 /***********************************************************************
122 */
123 static void upload_BLENDCOLOR(struct i915_context *i915)
124 {
125 unsigned bc[2];
126
127 memset(bc, 0, sizeof(bc));
128
129 /* I915_NEW_BLEND
130 */
131 {
132 const float *color = i915->blend_color.color;
133
134 bc[0] = _3DSTATE_CONST_BLEND_COLOR_CMD;
135 bc[1] = pack_ui32_float4(color[0],
136 color[1],
137 color[2],
138 color[3]);
139 }
140
141 set_dynamic_indirect(i915,
142 I915_DYNAMIC_BC_0,
143 bc,
144 2);
145 }
146
147 const struct i915_tracked_state i915_upload_BLENDCOLOR = {
148 "BLENDCOLOR",
149 upload_BLENDCOLOR,
150 I915_NEW_BLEND
151 };
152
153
154
155 /***********************************************************************
156 */
157 static void upload_IAB(struct i915_context *i915)
158 {
159 unsigned iab = i915->blend->iab;
160
161 set_dynamic_indirect(i915,
162 I915_DYNAMIC_IAB,
163 &iab,
164 1);
165 }
166
167 const struct i915_tracked_state i915_upload_IAB = {
168 "IAB",
169 upload_IAB,
170 I915_NEW_BLEND
171 };
172
173
174
175 /***********************************************************************
176 */
177 static void upload_DEPTHSCALE(struct i915_context *i915)
178 {
179 set_dynamic_indirect(i915,
180 I915_DYNAMIC_DEPTHSCALE_0,
181 &(i915->rasterizer->ds[0].u),
182 2);
183 }
184
185 const struct i915_tracked_state i915_upload_DEPTHSCALE = {
186 "DEPTHSCALE",
187 upload_DEPTHSCALE,
188 I915_NEW_RASTERIZER
189 };
190
191
192
193 /***********************************************************************
194 * Polygon stipple
195 *
196 * The i915 supports a 4x4 stipple natively, GL wants 32x32.
197 * Fortunately stipple is usually a repeating pattern.
198 *
199 * XXX: does stipple pattern need to be adjusted according to
200 * the window position?
201 *
202 * XXX: possibly need workaround for conform paths test.
203 */
204 static void upload_STIPPLE(struct i915_context *i915)
205 {
206 unsigned st[2];
207
208 st[0] = _3DSTATE_STIPPLE;
209 st[1] = 0;
210
211 /* I915_NEW_RASTERIZER
212 */
213 st[1] |= i915->rasterizer->st;
214
215 /* I915_NEW_STIPPLE
216 */
217 {
218 const ubyte *mask = (const ubyte *)i915->poly_stipple.stipple;
219 ubyte p[4];
220
221 p[0] = mask[12] & 0xf;
222 p[1] = mask[8] & 0xf;
223 p[2] = mask[4] & 0xf;
224 p[3] = mask[0] & 0xf;
225
226 /* Not sure what to do about fallbacks, so for now just dont:
227 */
228 st[1] |= ((p[0] << 0) |
229 (p[1] << 4) |
230 (p[2] << 8) |
231 (p[3] << 12));
232 }
233
234 set_dynamic_indirect(i915,
235 I915_DYNAMIC_STP_0,
236 &st[0],
237 2);
238 }
239
240 const struct i915_tracked_state i915_upload_STIPPLE = {
241 "STIPPLE",
242 upload_STIPPLE,
243 I915_NEW_RASTERIZER | I915_NEW_STIPPLE
244 };
245
246
247
248 /***********************************************************************
249 * Scissor enable
250 */
251 static void upload_SCISSOR_ENABLE( struct i915_context *i915 )
252 {
253 set_dynamic_indirect(i915,
254 I915_DYNAMIC_SC_ENA_0,
255 &(i915->rasterizer->sc[0]),
256 1);
257 }
258
259 const struct i915_tracked_state i915_upload_SCISSOR_ENABLE = {
260 "SCISSOR ENABLE",
261 upload_SCISSOR_ENABLE,
262 I915_NEW_RASTERIZER
263 };
264
265
266
267 /***********************************************************************
268 * Scissor rect
269 */
270 static void upload_SCISSOR_RECT(struct i915_context *i915)
271 {
272 unsigned x1 = i915->scissor.minx;
273 unsigned y1 = i915->scissor.miny;
274 unsigned x2 = i915->scissor.maxx;
275 unsigned y2 = i915->scissor.maxy;
276 unsigned sc[3];
277
278 sc[0] = _3DSTATE_SCISSOR_RECT_0_CMD;
279 sc[1] = (y1 << 16) | (x1 & 0xffff);
280 sc[2] = (y2 << 16) | (x2 & 0xffff);
281
282 set_dynamic_indirect(i915,
283 I915_DYNAMIC_SC_RECT_0,
284 &sc[0],
285 3);
286 }
287
288 const struct i915_tracked_state i915_upload_SCISSOR_RECT = {
289 "SCISSOR RECT",
290 upload_SCISSOR_RECT,
291 I915_NEW_SCISSOR
292 };
293
294
295
296 /***********************************************************************
297 */
298 static const struct i915_tracked_state *atoms[] = {
299 &i915_upload_MODES4,
300 &i915_upload_BFO,
301 &i915_upload_BLENDCOLOR,
302 &i915_upload_IAB,
303 &i915_upload_DEPTHSCALE,
304 &i915_upload_STIPPLE,
305 &i915_upload_SCISSOR_ENABLE,
306 &i915_upload_SCISSOR_RECT
307 };
308
309 /* These will be dynamic indirect state commands, but for now just end
310 * up on the batch buffer with everything else.
311 */
312 static void update_dynamic(struct i915_context *i915)
313 {
314 int i;
315
316 for (i = 0; i < Elements(atoms); i++)
317 if (i915->dirty & atoms[i]->dirty)
318 atoms[i]->update(i915);
319 }
320
321 struct i915_tracked_state i915_hw_dynamic = {
322 "dynamic",
323 update_dynamic,
324 ~0 /* all state atoms, becuase we do internal checking */
325 };