62dc819b32b78a8bf0942bfe2e463a86f548a98e
[mesa.git] / src / mesa / drivers / dri / i810 / i810state.c
1 /* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810state.c,v 1.9 2002/10/30 12:51:33 alanh Exp $ */
2
3 #include <stdio.h>
4
5 #include "glheader.h"
6 #include "buffers.h"
7 #include "context.h"
8 #include "macros.h"
9 #include "enums.h"
10 #include "dd.h"
11 #include "colormac.h"
12
13 #include "texmem.h"
14
15 #include "i810screen.h"
16 #include "i810_dri.h"
17
18 #include "i810context.h"
19 #include "i810state.h"
20 #include "i810tex.h"
21 #include "i810vb.h"
22 #include "i810tris.h"
23 #include "i810ioctl.h"
24
25 #include "swrast/swrast.h"
26 #include "array_cache/acache.h"
27 #include "tnl/tnl.h"
28 #include "swrast_setup/swrast_setup.h"
29
30 #include "tnl/t_pipeline.h"
31
32 static __inline__ GLuint i810PackColor(GLuint format,
33 GLubyte r, GLubyte g,
34 GLubyte b, GLubyte a)
35 {
36
37 if (I810_DEBUG&DEBUG_DRI)
38 fprintf(stderr, "%s\n", __FUNCTION__);
39
40 switch (format) {
41 case DV_PF_555:
42 return PACK_COLOR_1555( a, r, g, b );
43 case DV_PF_565:
44 return PACK_COLOR_565( r, g, b );
45 default:
46 fprintf(stderr, "unknown format %d\n", (int)format);
47 return 0;
48 }
49 }
50
51
52 static void i810AlphaFunc(GLcontext *ctx, GLenum func, GLfloat ref)
53 {
54 i810ContextPtr imesa = I810_CONTEXT(ctx);
55 GLuint a = (ZA_UPDATE_ALPHAFUNC|ZA_UPDATE_ALPHAREF);
56 GLubyte refByte;
57
58 CLAMPED_FLOAT_TO_UBYTE(refByte, ref);
59
60 switch (ctx->Color.AlphaFunc) {
61 case GL_NEVER: a |= ZA_ALPHA_NEVER; break;
62 case GL_LESS: a |= ZA_ALPHA_LESS; break;
63 case GL_GEQUAL: a |= ZA_ALPHA_GEQUAL; break;
64 case GL_LEQUAL: a |= ZA_ALPHA_LEQUAL; break;
65 case GL_GREATER: a |= ZA_ALPHA_GREATER; break;
66 case GL_NOTEQUAL: a |= ZA_ALPHA_NOTEQUAL; break;
67 case GL_EQUAL: a |= ZA_ALPHA_EQUAL; break;
68 case GL_ALWAYS: a |= ZA_ALPHA_ALWAYS; break;
69 default: return;
70 }
71
72 a |= ((refByte & 0xfc) << ZA_ALPHAREF_SHIFT);
73
74 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
75 imesa->Setup[I810_CTXREG_ZA] &= ~(ZA_ALPHA_MASK|ZA_ALPHAREF_MASK);
76 imesa->Setup[I810_CTXREG_ZA] |= a;
77 }
78
79 static void i810BlendEquationSeparate(GLcontext *ctx,
80 GLenum modeRGB, GLenum modeA)
81 {
82 assert( modeRGB == modeA );
83
84 /* Can only do GL_ADD equation in hardware */
85 FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_BLEND_EQ,
86 modeRGB != GL_FUNC_ADD);
87
88 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
89 * manner.
90 */
91 FALLBACK( I810_CONTEXT(ctx), I810_FALLBACK_LOGICOP,
92 (ctx->Color.ColorLogicOpEnabled &&
93 ctx->Color.LogicOp != GL_COPY));
94 }
95
96 static void i810BlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB,
97 GLenum dfactorRGB, GLenum sfactorA,
98 GLenum dfactorA )
99 {
100 i810ContextPtr imesa = I810_CONTEXT(ctx);
101 GLuint a = SDM_UPDATE_SRC_BLEND | SDM_UPDATE_DST_BLEND;
102 GLboolean fallback = GL_FALSE;
103
104 switch (ctx->Color.BlendSrcRGB) {
105 case GL_ZERO: a |= SDM_SRC_ZERO; break;
106 case GL_ONE: a |= SDM_SRC_ONE; break;
107 case GL_SRC_COLOR: a |= SDM_SRC_SRC_COLOR; break;
108 case GL_ONE_MINUS_SRC_COLOR: a |= SDM_SRC_INV_SRC_COLOR; break;
109 case GL_SRC_ALPHA: a |= SDM_SRC_SRC_ALPHA; break;
110 case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_SRC_INV_SRC_ALPHA; break;
111 case GL_DST_ALPHA: a |= SDM_SRC_ONE; break;
112 case GL_ONE_MINUS_DST_ALPHA: a |= SDM_SRC_ZERO; break;
113 case GL_DST_COLOR: a |= SDM_SRC_DST_COLOR; break;
114 case GL_ONE_MINUS_DST_COLOR: a |= SDM_SRC_INV_DST_COLOR; break;
115
116 /* (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0
117 * So (f, f, f, 1) = (0, 0, 0, 1). Since there is no destination alpha and
118 * the only supported alpha operation is GL_FUNC_ADD, the result modulating
119 * the source alpha with the alpha factor is largely irrelevant.
120 */
121 case GL_SRC_ALPHA_SATURATE: a |= SDM_SRC_ZERO; break;
122
123 case GL_CONSTANT_COLOR:
124 case GL_ONE_MINUS_CONSTANT_COLOR:
125 case GL_CONSTANT_ALPHA:
126 case GL_ONE_MINUS_CONSTANT_ALPHA:
127 fallback = GL_TRUE;
128 break;
129 default:
130 return;
131 }
132
133 switch (ctx->Color.BlendDstRGB) {
134 case GL_ZERO: a |= SDM_DST_ZERO; break;
135 case GL_ONE: a |= SDM_DST_ONE; break;
136 case GL_SRC_COLOR: a |= SDM_DST_SRC_COLOR; break;
137 case GL_ONE_MINUS_SRC_COLOR: a |= SDM_DST_INV_SRC_COLOR; break;
138 case GL_SRC_ALPHA: a |= SDM_DST_SRC_ALPHA; break;
139 case GL_ONE_MINUS_SRC_ALPHA: a |= SDM_DST_INV_SRC_ALPHA; break;
140 case GL_DST_ALPHA: a |= SDM_DST_ONE; break;
141 case GL_ONE_MINUS_DST_ALPHA: a |= SDM_DST_ZERO; break;
142 case GL_DST_COLOR: a |= SDM_DST_DST_COLOR; break;
143 case GL_ONE_MINUS_DST_COLOR: a |= SDM_DST_INV_DST_COLOR; break;
144
145 case GL_CONSTANT_COLOR:
146 case GL_ONE_MINUS_CONSTANT_COLOR:
147 case GL_CONSTANT_ALPHA:
148 case GL_ONE_MINUS_CONSTANT_ALPHA:
149 fallback = GL_TRUE;
150 break;
151 default:
152 return;
153 }
154
155 FALLBACK( imesa, I810_FALLBACK_BLEND_FUNC, fallback);
156 if (!fallback) {
157 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
158 imesa->Setup[I810_CTXREG_SDM] &= ~(SDM_SRC_MASK|SDM_DST_MASK);
159 imesa->Setup[I810_CTXREG_SDM] |= a;
160 }
161 }
162
163
164
165 static void i810DepthFunc(GLcontext *ctx, GLenum func)
166 {
167 i810ContextPtr imesa = I810_CONTEXT(ctx);
168 int zmode;
169
170 switch(func) {
171 case GL_NEVER: zmode = LCS_Z_NEVER; break;
172 case GL_ALWAYS: zmode = LCS_Z_ALWAYS; break;
173 case GL_LESS: zmode = LCS_Z_LESS; break;
174 case GL_LEQUAL: zmode = LCS_Z_LEQUAL; break;
175 case GL_EQUAL: zmode = LCS_Z_EQUAL; break;
176 case GL_GREATER: zmode = LCS_Z_GREATER; break;
177 case GL_GEQUAL: zmode = LCS_Z_GEQUAL; break;
178 case GL_NOTEQUAL: zmode = LCS_Z_NOTEQUAL; break;
179 default: return;
180 }
181
182 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
183 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_Z_MASK;
184 imesa->Setup[I810_CTXREG_LCS] |= zmode;
185 }
186
187 static void i810DepthMask(GLcontext *ctx, GLboolean flag)
188 {
189 i810ContextPtr imesa = I810_CONTEXT(ctx);
190 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
191
192 if (flag)
193 imesa->Setup[I810_CTXREG_B2] |= B2_ZB_WRITE_ENABLE;
194 else
195 imesa->Setup[I810_CTXREG_B2] &= ~B2_ZB_WRITE_ENABLE;
196 }
197
198
199 /* =============================================================
200 * Polygon stipple
201 *
202 * The i810 supports a 4x4 stipple natively, GL wants 32x32.
203 * Fortunately stipple is usually a repeating pattern.
204 */
205 static void i810PolygonStipple( GLcontext *ctx, const GLubyte *mask )
206 {
207 i810ContextPtr imesa = I810_CONTEXT(ctx);
208 const GLubyte *m = mask;
209 GLubyte p[4];
210 int i,j,k;
211 int active = (ctx->Polygon.StippleFlag &&
212 imesa->reduced_primitive == GL_TRIANGLES);
213 GLuint newMask;
214
215 if (active) {
216 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
217 imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
218 }
219
220 p[0] = mask[12] & 0xf; p[0] |= p[0] << 4;
221 p[1] = mask[8] & 0xf; p[1] |= p[1] << 4;
222 p[2] = mask[4] & 0xf; p[2] |= p[2] << 4;
223 p[3] = mask[0] & 0xf; p[3] |= p[3] << 4;
224
225 for (k = 0 ; k < 8 ; k++)
226 for (j = 0 ; j < 4; j++)
227 for (i = 0 ; i < 4 ; i++)
228 if (*m++ != p[j]) {
229 imesa->stipple_in_hw = 0;
230 return;
231 }
232
233 newMask = ((p[0] & 0xf) << 0) |
234 ((p[1] & 0xf) << 4) |
235 ((p[2] & 0xf) << 8) |
236 ((p[3] & 0xf) << 12);
237
238 if (newMask == 0xffff) {
239 /* this is needed to make conform pass */
240 imesa->stipple_in_hw = 0;
241 return;
242 }
243
244 imesa->Setup[I810_CTXREG_ST1] &= ~0xffff;
245 imesa->Setup[I810_CTXREG_ST1] |= newMask;
246 imesa->stipple_in_hw = 1;
247
248 if (active)
249 imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
250 }
251
252
253
254 /* =============================================================
255 * Hardware clipping
256 */
257
258
259 static void i810Scissor( GLcontext *ctx, GLint x, GLint y,
260 GLsizei w, GLsizei h )
261 {
262 i810ContextPtr imesa = I810_CONTEXT(ctx);
263
264 if (ctx->Scissor.Enabled) {
265 I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */
266 imesa->upload_cliprects = GL_TRUE;
267 }
268
269 imesa->scissor_rect.x1 = x;
270 imesa->scissor_rect.y1 = imesa->driDrawable->h - (y + h);
271 imesa->scissor_rect.x2 = x + w;
272 imesa->scissor_rect.y2 = imesa->driDrawable->h - y;
273 }
274
275
276 static void i810LogicOp( GLcontext *ctx, GLenum opcode )
277 {
278 i810ContextPtr imesa = I810_CONTEXT(ctx);
279 FALLBACK( imesa, I810_FALLBACK_LOGICOP,
280 (ctx->Color.ColorLogicOpEnabled && opcode != GL_COPY) );
281 }
282
283 /* Fallback to swrast for select and feedback.
284 */
285 static void i810RenderMode( GLcontext *ctx, GLenum mode )
286 {
287 i810ContextPtr imesa = I810_CONTEXT(ctx);
288 FALLBACK( imesa, I810_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
289 }
290
291
292 void i810DrawBuffer(GLcontext *ctx, GLenum mode )
293 {
294 i810ContextPtr imesa = I810_CONTEXT(ctx);
295 int front = 0;
296
297 /*
298 * _DrawDestMask is easier to cope with than <mode>.
299 */
300 switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0]) {
301 case BUFFER_BIT_FRONT_LEFT:
302 front = 1;
303 break;
304 case BUFFER_BIT_BACK_LEFT:
305 front = 0;
306 break;
307 default:
308 /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
309 FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_TRUE );
310 return;
311 }
312
313 if ( imesa->sarea->pf_current_page == 1 )
314 front ^= 1;
315
316 FALLBACK( imesa, I810_FALLBACK_DRAW_BUFFER, GL_FALSE );
317 I810_FIREVERTICES(imesa);
318 I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
319
320 if (front)
321 {
322 imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->fbOffset |
323 imesa->i810Screen->backPitchBits);
324 i810XMesaSetFrontClipRects( imesa );
325 }
326 else
327 {
328 imesa->BufferSetup[I810_DESTREG_DI1] = (imesa->i810Screen->backOffset |
329 imesa->i810Screen->backPitchBits);
330 i810XMesaSetBackClipRects( imesa );
331 }
332
333 /* We want to update the s/w rast state too so that r200SetBuffer()
334 * gets called.
335 */
336 _swrast_DrawBuffer(ctx, mode);
337 }
338
339
340 static void i810ReadBuffer(GLcontext *ctx, GLenum mode )
341 {
342 /* XXX anything? */
343 }
344
345
346 static void i810ClearColor(GLcontext *ctx, const GLfloat color[4] )
347 {
348 i810ContextPtr imesa = I810_CONTEXT(ctx);
349 GLubyte c[4];
350 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
351 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
352 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
353 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
354 imesa->ClearColor = i810PackColor( imesa->i810Screen->fbFormat,
355 c[0], c[1], c[2], c[3] );
356 }
357
358
359 /* =============================================================
360 * Culling - the i810 isn't quite as clean here as the rest of
361 * its interfaces, but it's not bad.
362 */
363 static void i810CullFaceFrontFace(GLcontext *ctx, GLenum unused)
364 {
365 i810ContextPtr imesa = I810_CONTEXT(ctx);
366 GLuint mode = LCS_CULL_BOTH;
367
368 if (ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK) {
369 mode = LCS_CULL_CW;
370 if (ctx->Polygon.CullFaceMode == GL_FRONT)
371 mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
372 if (ctx->Polygon.FrontFace != GL_CCW)
373 mode ^= (LCS_CULL_CW ^ LCS_CULL_CCW);
374 }
375
376 imesa->LcsCullMode = mode;
377
378 if (ctx->Polygon.CullFlag)
379 {
380 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
381 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
382 imesa->Setup[I810_CTXREG_LCS] |= mode;
383 }
384 }
385
386
387 static void i810LineWidth( GLcontext *ctx, GLfloat widthf )
388 {
389 i810ContextPtr imesa = I810_CONTEXT( ctx );
390 int width = (int)ctx->Line._Width;
391
392 imesa->LcsLineWidth = 0;
393 if (width & 1) imesa->LcsLineWidth |= LCS_LINEWIDTH_1_0;
394 if (width & 2) imesa->LcsLineWidth |= LCS_LINEWIDTH_2_0;
395
396 if (imesa->reduced_primitive == GL_LINES) {
397 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
398 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
399 imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsLineWidth;
400 }
401 }
402
403 static void i810PointSize( GLcontext *ctx, GLfloat sz )
404 {
405 i810ContextPtr imesa = I810_CONTEXT( ctx );
406 int size = (int)ctx->Point._Size;
407
408 imesa->LcsPointSize = 0;
409 if (size & 1) imesa->LcsPointSize |= LCS_LINEWIDTH_1_0;
410 if (size & 2) imesa->LcsPointSize |= LCS_LINEWIDTH_2_0;
411
412 if (imesa->reduced_primitive == GL_POINTS) {
413 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
414 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_3_0;
415 imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsPointSize;
416 }
417 }
418
419 /* =============================================================
420 * Color masks
421 */
422
423 static void i810ColorMask(GLcontext *ctx,
424 GLboolean r, GLboolean g,
425 GLboolean b, GLboolean a )
426 {
427 i810ContextPtr imesa = I810_CONTEXT( ctx );
428 GLuint tmp = 0;
429
430 if (r && g && b) {
431 tmp = imesa->Setup[I810_CTXREG_B2] | B2_FB_WRITE_ENABLE;
432 FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
433 } else if (!r && !g && !b) {
434 tmp = imesa->Setup[I810_CTXREG_B2] & ~B2_FB_WRITE_ENABLE;
435 FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_FALSE );
436 } else {
437 FALLBACK( imesa, I810_FALLBACK_COLORMASK, GL_TRUE );
438 return;
439 }
440
441 if (tmp != imesa->Setup[I810_CTXREG_B2]) {
442 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
443 imesa->Setup[I810_CTXREG_B2] = tmp;
444 imesa->dirty |= I810_UPLOAD_CTX;
445 }
446 }
447
448 /* Seperate specular not fully implemented on the i810.
449 */
450 static void i810LightModelfv(GLcontext *ctx, GLenum pname,
451 const GLfloat *param)
452 {
453 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
454 {
455 i810ContextPtr imesa = I810_CONTEXT( ctx );
456 FALLBACK( imesa, I810_FALLBACK_SPECULAR,
457 (ctx->Light.Enabled &&
458 ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR));
459 }
460 }
461
462 /* But the 815 has it...
463 */
464 static void i810LightModelfv_i815(GLcontext *ctx, GLenum pname,
465 const GLfloat *param)
466 {
467 if (pname == GL_LIGHT_MODEL_COLOR_CONTROL)
468 {
469 i810ContextPtr imesa = I810_CONTEXT( ctx );
470
471 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
472 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)
473 imesa->Setup[I810_CTXREG_B1] |= B1_SPEC_ENABLE;
474 else
475 imesa->Setup[I810_CTXREG_B1] &= ~B1_SPEC_ENABLE;
476 }
477 }
478
479 /* In Mesa 3.5 we can reliably do native flatshading.
480 */
481 static void i810ShadeModel(GLcontext *ctx, GLenum mode)
482 {
483 i810ContextPtr imesa = I810_CONTEXT(ctx);
484 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
485 if (mode == GL_FLAT)
486 imesa->Setup[I810_CTXREG_LCS] |= LCS_INTERP_FLAT;
487 else
488 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_INTERP_FLAT;
489 }
490
491
492
493 /* =============================================================
494 * Fog
495 */
496 static void i810Fogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
497 {
498 i810ContextPtr imesa = I810_CONTEXT(ctx);
499
500 if (pname == GL_FOG_COLOR) {
501 GLuint color = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
502 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
503 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
504
505 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
506 imesa->Setup[I810_CTXREG_FOG] = ((GFX_OP_FOG_COLOR | color) &
507 ~FOG_RESERVED_MASK);
508 }
509 }
510
511
512 /* =============================================================
513 */
514 static void i810Enable(GLcontext *ctx, GLenum cap, GLboolean state)
515 {
516 i810ContextPtr imesa = I810_CONTEXT(ctx);
517
518 switch(cap) {
519 case GL_ALPHA_TEST:
520 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
521 imesa->Setup[I810_CTXREG_B1] &= ~B1_ALPHA_TEST_ENABLE;
522 if (state)
523 imesa->Setup[I810_CTXREG_B1] |= B1_ALPHA_TEST_ENABLE;
524 break;
525 case GL_BLEND:
526 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
527 imesa->Setup[I810_CTXREG_B1] &= ~B1_BLEND_ENABLE;
528 if (state)
529 imesa->Setup[I810_CTXREG_B1] |= B1_BLEND_ENABLE;
530
531 /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
532 */
533 FALLBACK( imesa, I810_FALLBACK_LOGICOP,
534 (ctx->Color.ColorLogicOpEnabled &&
535 ctx->Color.LogicOp != GL_COPY));
536 break;
537 case GL_DEPTH_TEST:
538 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
539 imesa->Setup[I810_CTXREG_B1] &= ~B1_Z_TEST_ENABLE;
540 if (state)
541 imesa->Setup[I810_CTXREG_B1] |= B1_Z_TEST_ENABLE;
542 break;
543 case GL_SCISSOR_TEST:
544 /* XXX without these next two lines, conform's scissor test fails */
545 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
546 I810_STATECHANGE(imesa, I810_UPLOAD_BUFFERS);
547 I810_FIREVERTICES(imesa); /* don't pipeline cliprect changes */
548 imesa->upload_cliprects = GL_TRUE;
549 imesa->scissor = state;
550 break;
551 case GL_POLYGON_STIPPLE:
552 if (imesa->stipple_in_hw && imesa->reduced_primitive == GL_TRIANGLES)
553 {
554 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
555 imesa->Setup[I810_CTXREG_ST1] &= ~ST1_ENABLE;
556 if (state)
557 imesa->Setup[I810_CTXREG_ST1] |= ST1_ENABLE;
558 }
559 break;
560 case GL_LINE_SMOOTH:
561 /* Need to fatten the lines by .5, or they disappear...
562 */
563 if (imesa->reduced_primitive == GL_LINES) {
564 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
565 imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
566 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
567 if (state) {
568 imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
569 imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
570 }
571 }
572 break;
573 case GL_POINT_SMOOTH:
574 if (imesa->reduced_primitive == GL_POINTS) {
575 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
576 imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
577 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_LINEWIDTH_0_5;
578 if (state) {
579 imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
580 imesa->Setup[I810_CTXREG_LCS] |= LCS_LINEWIDTH_0_5;
581 }
582 }
583 break;
584 case GL_POLYGON_SMOOTH:
585 if (imesa->reduced_primitive == GL_TRIANGLES) {
586 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
587 imesa->Setup[I810_CTXREG_AA] &= ~AA_ENABLE;
588 if (state)
589 imesa->Setup[I810_CTXREG_AA] |= AA_ENABLE;
590 }
591 break;
592 case GL_FOG:
593 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
594 imesa->Setup[I810_CTXREG_B1] &= ~B1_FOG_ENABLE;
595 if (state)
596 imesa->Setup[I810_CTXREG_B1] |= B1_FOG_ENABLE;
597 break;
598 case GL_CULL_FACE:
599 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
600 imesa->Setup[I810_CTXREG_LCS] &= ~LCS_CULL_MASK;
601 if (state)
602 imesa->Setup[I810_CTXREG_LCS] |= imesa->LcsCullMode;
603 else
604 imesa->Setup[I810_CTXREG_LCS] |= LCS_CULL_DISABLE;
605 break;
606 case GL_TEXTURE_2D:
607 I810_STATECHANGE(imesa, I810_UPLOAD_CTX);
608 if (ctx->Texture.CurrentUnit == 0) {
609 imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL0_ENABLE;
610 if (state)
611 imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL0_ENABLE;
612 } else {
613 imesa->Setup[I810_CTXREG_MT] &= ~MT_TEXEL1_ENABLE;
614 if (state)
615 imesa->Setup[I810_CTXREG_MT] |= MT_TEXEL1_ENABLE;
616 }
617 break;
618 case GL_COLOR_LOGIC_OP:
619 FALLBACK( imesa, I810_FALLBACK_LOGICOP,
620 (state && ctx->Color.LogicOp != GL_COPY));
621 break;
622 case GL_STENCIL_TEST:
623 FALLBACK( imesa, I810_FALLBACK_STENCIL, state );
624 break;
625 default:
626 ;
627 }
628 }
629
630
631
632
633
634
635
636 /* =============================================================
637 */
638
639
640
641
642 void i810EmitDrawingRectangle( i810ContextPtr imesa )
643 {
644 __DRIdrawablePrivate *dPriv = imesa->driDrawable;
645 i810ScreenPrivate *i810Screen = imesa->i810Screen;
646 int x0 = imesa->drawX;
647 int y0 = imesa->drawY;
648 int x1 = x0 + dPriv->w;
649 int y1 = y0 + dPriv->h;
650 GLuint dr2, dr3, dr4;
651
652
653 /* Coordinate origin of the window - may be offscreen.
654 */
655 dr4 = imesa->BufferSetup[I810_DESTREG_DR4] = ((y0<<16) |
656 (((unsigned)x0)&0xFFFF));
657
658 /* Clip to screen.
659 */
660 if (x0 < 0) x0 = 0;
661 if (y0 < 0) y0 = 0;
662 if (x1 > i810Screen->width-1) x1 = i810Screen->width-1;
663 if (y1 > i810Screen->height-1) y1 = i810Screen->height-1;
664
665
666 /* Onscreen drawing rectangle.
667 */
668 dr2 = imesa->BufferSetup[I810_DESTREG_DR2] = ((y0<<16) | x0);
669 dr3 = imesa->BufferSetup[I810_DESTREG_DR3] = (((y1+1)<<16) | (x1+1));
670
671
672 imesa->dirty |= I810_UPLOAD_BUFFERS;
673 }
674
675
676
677 static void i810CalcViewport( GLcontext *ctx )
678 {
679 i810ContextPtr imesa = I810_CONTEXT(ctx);
680 const GLfloat *v = ctx->Viewport._WindowMap.m;
681 GLfloat *m = imesa->ViewportMatrix.m;
682
683 /* See also i810_translate_vertex. SUBPIXEL adjustments can be done
684 * via state vars, too.
685 */
686 m[MAT_SX] = v[MAT_SX];
687 m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X;
688 m[MAT_SY] = - v[MAT_SY];
689 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + SUBPIXEL_Y;
690 m[MAT_SZ] = v[MAT_SZ] * (1.0 / 0xffff);
691 m[MAT_TZ] = v[MAT_TZ] * (1.0 / 0xffff);
692 }
693
694 static void i810Viewport( GLcontext *ctx,
695 GLint x, GLint y,
696 GLsizei width, GLsizei height )
697 {
698 /* update size of Mesa/software ancillary buffers */
699 _mesa_ResizeBuffersMESA();
700 i810CalcViewport( ctx );
701 }
702
703 static void i810DepthRange( GLcontext *ctx,
704 GLclampd nearval, GLclampd farval )
705 {
706 i810CalcViewport( ctx );
707 }
708
709
710
711 void i810PrintDirty( const char *msg, GLuint state )
712 {
713 fprintf(stderr, "%s (0x%x): %s%s%s%s\n",
714 msg,
715 (unsigned int) state,
716 (state & I810_UPLOAD_TEX0) ? "upload-tex0, " : "",
717 (state & I810_UPLOAD_TEX1) ? "upload-tex1, " : "",
718 (state & I810_UPLOAD_CTX) ? "upload-ctx, " : "",
719 (state & I810_UPLOAD_BUFFERS) ? "upload-bufs, " : ""
720 );
721 }
722
723
724
725 void i810InitState( GLcontext *ctx )
726 {
727 i810ContextPtr imesa = I810_CONTEXT(ctx);
728 i810ScreenPrivate *i810Screen = imesa->i810Screen;
729
730 memset(imesa->Setup, 0, sizeof(imesa->Setup));
731
732 imesa->Setup[I810_CTXREG_VF] = 0;
733
734 imesa->Setup[I810_CTXREG_MT] = (GFX_OP_MAP_TEXELS |
735 MT_UPDATE_TEXEL1_STATE |
736 MT_TEXEL1_COORD1 |
737 MT_TEXEL1_MAP1 |
738 MT_TEXEL1_DISABLE |
739 MT_UPDATE_TEXEL0_STATE |
740 MT_TEXEL0_COORD0 |
741 MT_TEXEL0_MAP0 |
742 MT_TEXEL0_DISABLE);
743
744 imesa->Setup[I810_CTXREG_MC0] = ( GFX_OP_MAP_COLOR_STAGES |
745 MC_STAGE_0 |
746 MC_UPDATE_DEST |
747 MC_DEST_CURRENT |
748 MC_UPDATE_ARG1 |
749 MC_ARG1_ITERATED_COLOR |
750 MC_ARG1_DONT_REPLICATE_ALPHA |
751 MC_ARG1_DONT_INVERT |
752 MC_UPDATE_ARG2 |
753 MC_ARG2_ONE |
754 MC_ARG2_DONT_REPLICATE_ALPHA |
755 MC_ARG2_DONT_INVERT |
756 MC_UPDATE_OP |
757 MC_OP_ARG1 );
758
759 imesa->Setup[I810_CTXREG_MC1] = ( GFX_OP_MAP_COLOR_STAGES |
760 MC_STAGE_1 |
761 MC_UPDATE_DEST |
762 MC_DEST_CURRENT |
763 MC_UPDATE_ARG1 |
764 MC_ARG1_ONE |
765 MC_ARG1_DONT_REPLICATE_ALPHA |
766 MC_ARG1_DONT_INVERT |
767 MC_UPDATE_ARG2 |
768 MC_ARG2_ONE |
769 MC_ARG2_DONT_REPLICATE_ALPHA |
770 MC_ARG2_DONT_INVERT |
771 MC_UPDATE_OP |
772 MC_OP_DISABLE );
773
774
775 imesa->Setup[I810_CTXREG_MC2] = ( GFX_OP_MAP_COLOR_STAGES |
776 MC_STAGE_2 |
777 MC_UPDATE_DEST |
778 MC_DEST_CURRENT |
779 MC_UPDATE_ARG1 |
780 MC_ARG1_CURRENT_COLOR |
781 MC_ARG1_REPLICATE_ALPHA |
782 MC_ARG1_DONT_INVERT |
783 MC_UPDATE_ARG2 |
784 MC_ARG2_ONE |
785 MC_ARG2_DONT_REPLICATE_ALPHA |
786 MC_ARG2_DONT_INVERT |
787 MC_UPDATE_OP |
788 MC_OP_DISABLE );
789
790
791 imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES |
792 MA_STAGE_0 |
793 MA_UPDATE_ARG1 |
794 MA_ARG1_ITERATED_ALPHA |
795 MA_ARG1_DONT_INVERT |
796 MA_UPDATE_ARG2 |
797 MA_ARG2_CURRENT_ALPHA |
798 MA_ARG2_DONT_INVERT |
799 MA_UPDATE_OP |
800 MA_OP_ARG1 );
801
802
803 imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES |
804 MA_STAGE_1 |
805 MA_UPDATE_ARG1 |
806 MA_ARG1_CURRENT_ALPHA |
807 MA_ARG1_DONT_INVERT |
808 MA_UPDATE_ARG2 |
809 MA_ARG2_CURRENT_ALPHA |
810 MA_ARG2_DONT_INVERT |
811 MA_UPDATE_OP |
812 MA_OP_ARG1 );
813
814
815 imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES |
816 MA_STAGE_2 |
817 MA_UPDATE_ARG1 |
818 MA_ARG1_CURRENT_ALPHA |
819 MA_ARG1_DONT_INVERT |
820 MA_UPDATE_ARG2 |
821 MA_ARG2_CURRENT_ALPHA |
822 MA_ARG2_DONT_INVERT |
823 MA_UPDATE_OP |
824 MA_OP_ARG1 );
825
826
827 imesa->Setup[I810_CTXREG_SDM] = ( GFX_OP_SRC_DEST_MONO |
828 SDM_UPDATE_MONO_ENABLE |
829 0 |
830 SDM_UPDATE_SRC_BLEND |
831 SDM_SRC_ONE |
832 SDM_UPDATE_DST_BLEND |
833 SDM_DST_ZERO );
834
835 /* Use for colormask:
836 */
837 imesa->Setup[I810_CTXREG_CF0] = GFX_OP_COLOR_FACTOR;
838 imesa->Setup[I810_CTXREG_CF1] = 0xffffffff;
839
840 imesa->Setup[I810_CTXREG_ZA] = (GFX_OP_ZBIAS_ALPHAFUNC |
841 ZA_UPDATE_ALPHAFUNC |
842 ZA_ALPHA_ALWAYS |
843 ZA_UPDATE_ZBIAS |
844 0 |
845 ZA_UPDATE_ALPHAREF |
846 0x0);
847
848 imesa->Setup[I810_CTXREG_FOG] = (GFX_OP_FOG_COLOR |
849 (0xffffff & ~FOG_RESERVED_MASK));
850
851 /* Choose a pipe
852 */
853 imesa->Setup[I810_CTXREG_B1] = ( GFX_OP_BOOL_1 |
854 B1_UPDATE_SPEC_SETUP_ENABLE |
855 0 |
856 B1_UPDATE_ALPHA_SETUP_ENABLE |
857 B1_ALPHA_SETUP_ENABLE |
858 B1_UPDATE_CI_KEY_ENABLE |
859 0 |
860 B1_UPDATE_CHROMAKEY_ENABLE |
861 0 |
862 B1_UPDATE_Z_BIAS_ENABLE |
863 0 |
864 B1_UPDATE_SPEC_ENABLE |
865 0 |
866 B1_UPDATE_FOG_ENABLE |
867 0 |
868 B1_UPDATE_ALPHA_TEST_ENABLE |
869 0 |
870 B1_UPDATE_BLEND_ENABLE |
871 0 |
872 B1_UPDATE_Z_TEST_ENABLE |
873 0 );
874
875 imesa->Setup[I810_CTXREG_B2] = ( GFX_OP_BOOL_2 |
876 B2_UPDATE_MAP_CACHE_ENABLE |
877 B2_MAP_CACHE_ENABLE |
878 B2_UPDATE_ALPHA_DITHER_ENABLE |
879 0 |
880 B2_UPDATE_FOG_DITHER_ENABLE |
881 0 |
882 B2_UPDATE_SPEC_DITHER_ENABLE |
883 0 |
884 B2_UPDATE_RGB_DITHER_ENABLE |
885 B2_RGB_DITHER_ENABLE |
886 B2_UPDATE_FB_WRITE_ENABLE |
887 B2_FB_WRITE_ENABLE |
888 B2_UPDATE_ZB_WRITE_ENABLE |
889 B2_ZB_WRITE_ENABLE );
890
891 imesa->Setup[I810_CTXREG_LCS] = ( GFX_OP_LINEWIDTH_CULL_SHADE_MODE |
892 LCS_UPDATE_ZMODE |
893 LCS_Z_LESS |
894 LCS_UPDATE_LINEWIDTH |
895 LCS_LINEWIDTH_1_0 |
896 LCS_UPDATE_ALPHA_INTERP |
897 LCS_ALPHA_INTERP |
898 LCS_UPDATE_FOG_INTERP |
899 0 |
900 LCS_UPDATE_SPEC_INTERP |
901 0 |
902 LCS_UPDATE_RGB_INTERP |
903 LCS_RGB_INTERP |
904 LCS_UPDATE_CULL_MODE |
905 LCS_CULL_DISABLE);
906
907 imesa->LcsCullMode = LCS_CULL_CW;
908 imesa->LcsLineWidth = LCS_LINEWIDTH_1_0;
909 imesa->LcsPointSize = LCS_LINEWIDTH_1_0;
910
911 imesa->Setup[I810_CTXREG_PV] = ( GFX_OP_PV_RULE |
912 PV_UPDATE_PIXRULE |
913 PV_PIXRULE_ENABLE |
914 PV_UPDATE_LINELIST |
915 PV_LINELIST_PV1 |
916 PV_UPDATE_TRIFAN |
917 PV_TRIFAN_PV2 |
918 PV_UPDATE_TRISTRIP |
919 PV_TRISTRIP_PV2 );
920
921
922 imesa->Setup[I810_CTXREG_ST0] = GFX_OP_STIPPLE;
923 imesa->Setup[I810_CTXREG_ST1] = 0;
924
925 imesa->Setup[I810_CTXREG_AA] = ( GFX_OP_ANTIALIAS |
926 AA_UPDATE_EDGEFLAG |
927 0 |
928 AA_UPDATE_POLYWIDTH |
929 AA_POLYWIDTH_05 |
930 AA_UPDATE_LINEWIDTH |
931 AA_LINEWIDTH_05 |
932 AA_UPDATE_BB_EXPANSION |
933 0 |
934 AA_UPDATE_AA_ENABLE |
935 0 );
936
937 memset(imesa->BufferSetup, 0, sizeof(imesa->BufferSetup));
938 imesa->BufferSetup[I810_DESTREG_DI0] = CMD_OP_DESTBUFFER_INFO;
939
940 if (imesa->glCtx->Visual.doubleBufferMode && imesa->sarea->pf_current_page == 0) {
941 /* use back buffer by default */
942 imesa->drawMap = i810Screen->back.map;
943 imesa->readMap = i810Screen->back.map;
944 imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->backOffset |
945 i810Screen->backPitchBits);
946 } else {
947 /* use front buffer by default */
948 imesa->drawMap = (char *)imesa->driScreen->pFB;
949 imesa->readMap = (char *)imesa->driScreen->pFB;
950 imesa->BufferSetup[I810_DESTREG_DI1] = (i810Screen->fbOffset |
951 i810Screen->backPitchBits);
952 }
953
954 imesa->BufferSetup[I810_DESTREG_DV0] = GFX_OP_DESTBUFFER_VARS;
955 imesa->BufferSetup[I810_DESTREG_DV1] = (DV_HORG_BIAS_OGL |
956 DV_VORG_BIAS_OGL |
957 i810Screen->fbFormat);
958
959 imesa->BufferSetup[I810_DESTREG_DR0] = GFX_OP_DRAWRECT_INFO;
960 imesa->BufferSetup[I810_DESTREG_DR1] = DR1_RECT_CLIP_ENABLE;
961 }
962
963
964 static void i810InvalidateState( GLcontext *ctx, GLuint new_state )
965 {
966 _swrast_InvalidateState( ctx, new_state );
967 _swsetup_InvalidateState( ctx, new_state );
968 _ac_InvalidateState( ctx, new_state );
969 _tnl_InvalidateState( ctx, new_state );
970 I810_CONTEXT(ctx)->new_state |= new_state;
971 }
972
973
974 void i810InitStateFuncs(GLcontext *ctx)
975 {
976 /* Callbacks for internal Mesa events.
977 */
978 ctx->Driver.UpdateState = i810InvalidateState;
979
980 /* API callbacks
981 */
982 ctx->Driver.AlphaFunc = i810AlphaFunc;
983 ctx->Driver.BlendEquationSeparate = i810BlendEquationSeparate;
984 ctx->Driver.BlendFuncSeparate = i810BlendFuncSeparate;
985 ctx->Driver.ClearColor = i810ClearColor;
986 ctx->Driver.ColorMask = i810ColorMask;
987 ctx->Driver.CullFace = i810CullFaceFrontFace;
988 ctx->Driver.DepthFunc = i810DepthFunc;
989 ctx->Driver.DepthMask = i810DepthMask;
990 ctx->Driver.Enable = i810Enable;
991 ctx->Driver.Fogfv = i810Fogfv;
992 ctx->Driver.FrontFace = i810CullFaceFrontFace;
993 ctx->Driver.LineWidth = i810LineWidth;
994 ctx->Driver.LogicOpcode = i810LogicOp;
995 ctx->Driver.PolygonStipple = i810PolygonStipple;
996 ctx->Driver.RenderMode = i810RenderMode;
997 ctx->Driver.Scissor = i810Scissor;
998 ctx->Driver.DrawBuffer = i810DrawBuffer;
999 ctx->Driver.ReadBuffer = i810ReadBuffer;
1000 ctx->Driver.ShadeModel = i810ShadeModel;
1001 ctx->Driver.DepthRange = i810DepthRange;
1002 ctx->Driver.Viewport = i810Viewport;
1003 ctx->Driver.PointSize = i810PointSize;
1004
1005 if (IS_I815(I810_CONTEXT(ctx))) {
1006 ctx->Driver.LightModelfv = i810LightModelfv_i815;
1007 } else {
1008 ctx->Driver.LightModelfv = i810LightModelfv;
1009 }
1010
1011 /* Pixel path fallbacks.
1012 */
1013 ctx->Driver.Accum = _swrast_Accum;
1014 ctx->Driver.Bitmap = _swrast_Bitmap;
1015 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1016 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1017 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1018
1019 /* Swrast hooks for imaging extensions:
1020 */
1021 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1022 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1023 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1024 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1025 }