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