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