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