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