Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / r128 / r128_state.c
1 /**************************************************************************
2
3 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
4                                                Cedar Park, Texas.
5 All Rights Reserved.
6
7 Permission is hereby granted, free of charge, to any person obtaining a
8 copy of this software and associated documentation files (the "Software"),
9 to deal in the Software without restriction, including without limitation
10 on the rights to use, copy, modify, merge, publish, distribute, sub
11 license, and/or sell copies of the Software, and to permit persons to whom
12 the Software is furnished to do so, subject to the following conditions:
13
14 The above copyright notice and this permission notice (including the next
15 paragraph) shall be included in all copies or substantial portions of the
16 Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 USE OR OTHER DEALINGS IN THE SOFTWARE.
25
26 **************************************************************************/
27
28 /*
29  * Authors:
30  *   Gareth Hughes <gareth@valinux.com>
31  *   Kevin E. Martin <martin@valinux.com>
32  *   Keith Whitwell <keith@tungstengraphics.com>
33  *
34  */
35
36 #include "r128_context.h"
37 #include "r128_state.h"
38 #include "r128_ioctl.h"
39 #include "r128_tris.h"
40 #include "r128_tex.h"
41
42 #include "main/context.h"
43 #include "main/enums.h"
44 #include "main/colormac.h"
45 #include "main/macros.h"
46 #include "main/state.h"
47 #include "swrast/swrast.h"
48 #include "vbo/vbo.h"
49 #include "tnl/tnl.h"
50 #include "swrast_setup/swrast_setup.h"
51
52 #include "drirenderbuffer.h"
53
54
55 /* =============================================================
56  * Alpha blending
57  */
58
59
60 /**
61  * Calculate the hardware blend factor setting.  This same function is used
62  * for source and destination of both alpha and RGB.  
63  *
64  * \returns
65  * The hardware register value for the specified blend factor.  This value
66  * will need to be shifted into the correct position for either source or
67  * destination factor.
68  *
69  * \todo
70  * Since the two cases where source and destination are handled differently
71  * are essentially error cases, they should never happen.  Determine if these
72  * cases can be removed.
73  */
74 static int blend_factor( r128ContextPtr rmesa, GLenum factor, GLboolean is_src )
75 {
76    int   func;
77
78    switch ( factor ) {
79    case GL_ZERO:
80       func = R128_ALPHA_BLEND_ZERO;
81       break;
82    case GL_ONE:
83       func = R128_ALPHA_BLEND_ONE;
84       break;
85
86    case GL_SRC_COLOR:
87       func = R128_ALPHA_BLEND_SRCCOLOR;
88       break;
89    case GL_ONE_MINUS_SRC_COLOR:
90       func = R128_ALPHA_BLEND_INVSRCCOLOR;
91       break;
92    case GL_SRC_ALPHA:
93       func = R128_ALPHA_BLEND_SRCALPHA;
94       break;
95    case GL_ONE_MINUS_SRC_ALPHA:
96       func = R128_ALPHA_BLEND_INVSRCALPHA;
97       break;
98    case GL_SRC_ALPHA_SATURATE:
99       func = (is_src) ? R128_ALPHA_BLEND_SAT : R128_ALPHA_BLEND_ZERO;
100       break;
101
102    case GL_DST_COLOR:
103       func = R128_ALPHA_BLEND_DSTCOLOR;
104       break;
105    case GL_ONE_MINUS_DST_COLOR:
106       func = R128_ALPHA_BLEND_INVDSTCOLOR;
107       break;
108    case GL_DST_ALPHA:
109       func = R128_ALPHA_BLEND_DSTALPHA;
110       break;
111    case GL_ONE_MINUS_DST_ALPHA:
112       func = R128_ALPHA_BLEND_INVDSTALPHA;
113       break;
114
115    case GL_CONSTANT_COLOR:
116    case GL_ONE_MINUS_CONSTANT_COLOR:
117    case GL_CONSTANT_ALPHA:
118    case GL_ONE_MINUS_CONSTANT_ALPHA:
119    default:
120       FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_TRUE );
121       func = (is_src) ? R128_ALPHA_BLEND_ONE : R128_ALPHA_BLEND_ZERO;
122       break;
123    }
124    
125    return func;
126 }
127
128
129 static void r128UpdateAlphaMode( struct gl_context *ctx )
130 {
131    r128ContextPtr rmesa = R128_CONTEXT(ctx);
132    GLuint a = rmesa->setup.misc_3d_state_cntl_reg;
133    GLuint t = rmesa->setup.tex_cntl_c;
134
135    if ( ctx->Color.AlphaEnabled ) {
136       GLubyte ref;
137
138       CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef);
139
140       a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK);
141
142       switch ( ctx->Color.AlphaFunc ) {
143       case GL_NEVER:
144          a |= R128_ALPHA_TEST_NEVER;
145          break;
146       case GL_LESS:
147          a |= R128_ALPHA_TEST_LESS;
148          break;
149       case GL_LEQUAL:
150          a |= R128_ALPHA_TEST_LESSEQUAL;
151          break;
152       case GL_EQUAL:
153          a |= R128_ALPHA_TEST_EQUAL;
154          break;
155       case GL_GEQUAL:
156          a |= R128_ALPHA_TEST_GREATEREQUAL;
157          break;
158       case GL_GREATER:
159          a |= R128_ALPHA_TEST_GREATER;
160          break;
161       case GL_NOTEQUAL:
162          a |= R128_ALPHA_TEST_NEQUAL;
163          break;
164       case GL_ALWAYS:
165          a |= R128_ALPHA_TEST_ALWAYS;
166          break;
167       }
168
169       a |= ref & R128_REF_ALPHA_MASK;
170       t |= R128_ALPHA_TEST_ENABLE;
171    } else {
172       t &= ~R128_ALPHA_TEST_ENABLE;
173    }
174
175    FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_FALSE );
176
177    if ( ctx->Color.BlendEnabled ) {
178       a &= ~((R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_SRC_SHIFT) |
179              (R128_ALPHA_BLEND_MASK << R128_ALPHA_BLEND_DST_SHIFT)
180              | R128_ALPHA_COMB_FCN_MASK);
181
182       a |= blend_factor( rmesa, ctx->Color.Blend[0].SrcRGB, GL_TRUE ) 
183           << R128_ALPHA_BLEND_SRC_SHIFT;
184       a |= blend_factor( rmesa, ctx->Color.Blend[0].DstRGB, GL_FALSE ) 
185           << R128_ALPHA_BLEND_DST_SHIFT;
186
187       switch (ctx->Color.Blend[0].EquationRGB) {
188       case GL_FUNC_ADD:
189          a |= R128_ALPHA_COMB_ADD_CLAMP;
190          break;
191       case GL_FUNC_SUBTRACT:
192          a |= R128_ALPHA_COMB_SUB_SRC_DST_CLAMP;
193          break;
194       default:
195          FALLBACK( rmesa, R128_FALLBACK_BLEND_EQ, GL_TRUE );
196       }
197
198       t |=  R128_ALPHA_ENABLE;
199    } else {
200       t &= ~R128_ALPHA_ENABLE;
201    }
202
203    if ( rmesa->setup.misc_3d_state_cntl_reg != a ) {
204       rmesa->setup.misc_3d_state_cntl_reg = a;
205       rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
206    }
207    if ( rmesa->setup.tex_cntl_c != t ) {
208       rmesa->setup.tex_cntl_c = t;
209       rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
210    }
211 }
212
213 static void r128DDAlphaFunc( struct gl_context *ctx, GLenum func, GLfloat ref )
214 {
215    r128ContextPtr rmesa = R128_CONTEXT(ctx);
216
217    FLUSH_BATCH( rmesa );
218    rmesa->new_state |= R128_NEW_ALPHA;
219 }
220
221 static void r128DDBlendEquationSeparate( struct gl_context *ctx, 
222                                          GLenum modeRGB, GLenum modeA )
223 {
224    r128ContextPtr rmesa = R128_CONTEXT(ctx);
225
226    assert( modeRGB == modeA );
227    FLUSH_BATCH( rmesa );
228
229    /* BlendEquation sets ColorLogicOpEnabled in an unexpected
230     * manner.
231     */
232    FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_LOGICOP,
233              (ctx->Color.ColorLogicOpEnabled &&
234               ctx->Color.LogicOp != GL_COPY));
235
236    /* Can only do blend addition, not min, max, subtract, etc. */
237    FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_BLEND_EQ,
238              (modeRGB != GL_FUNC_ADD) && (modeRGB != GL_FUNC_SUBTRACT));
239
240    rmesa->new_state |= R128_NEW_ALPHA;
241 }
242
243 static void r128DDBlendFuncSeparate( struct gl_context *ctx,
244                                      GLenum sfactorRGB, GLenum dfactorRGB,
245                                      GLenum sfactorA, GLenum dfactorA )
246 {
247    r128ContextPtr rmesa = R128_CONTEXT(ctx);
248
249    FLUSH_BATCH( rmesa );
250    rmesa->new_state |= R128_NEW_ALPHA;
251 }
252
253 /* =============================================================
254  * Stencil
255  */
256
257 static void
258 r128DDStencilFuncSeparate( struct gl_context *ctx, GLenum face, GLenum func,
259                            GLint ref, GLuint mask )
260 {
261    r128ContextPtr rmesa = R128_CONTEXT(ctx);
262    GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
263                      ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
264                      ((ctx->Stencil.WriteMask[0] & 0xff) << 24)); 
265    GLuint z = rmesa->setup.z_sten_cntl_c;
266
267    z &= ~R128_STENCIL_TEST_MASK;
268    switch ( ctx->Stencil.Function[0] ) {
269    case GL_NEVER:
270       z |= R128_STENCIL_TEST_NEVER;
271       break;
272    case GL_LESS:
273       z |= R128_STENCIL_TEST_LESS;
274       break;
275    case GL_EQUAL:
276       z |= R128_STENCIL_TEST_EQUAL;
277       break;
278    case GL_LEQUAL:
279       z |= R128_STENCIL_TEST_LESSEQUAL;
280       break;
281    case GL_GREATER:
282       z |= R128_STENCIL_TEST_GREATER;
283       break;
284    case GL_NOTEQUAL:
285       z |= R128_STENCIL_TEST_NEQUAL;
286       break;
287    case GL_GEQUAL:
288       z |= R128_STENCIL_TEST_GREATEREQUAL;
289       break;
290    case GL_ALWAYS:
291       z |= R128_STENCIL_TEST_ALWAYS;
292       break;
293    }
294
295    if ( rmesa->setup.sten_ref_mask_c != refmask ) {
296       rmesa->setup.sten_ref_mask_c = refmask;
297       rmesa->dirty |= R128_UPLOAD_MASKS;
298    }
299    if ( rmesa->setup.z_sten_cntl_c != z ) {
300       rmesa->setup.z_sten_cntl_c = z;
301       rmesa->dirty |= R128_UPLOAD_CONTEXT;
302    }
303 }
304
305 static void
306 r128DDStencilMaskSeparate( struct gl_context *ctx, GLenum face, GLuint mask )
307 {
308    r128ContextPtr rmesa = R128_CONTEXT(ctx);
309    GLuint refmask = (((ctx->Stencil.Ref[0] & 0xff) << 0) |
310                      ((ctx->Stencil.ValueMask[0] & 0xff) << 16) |
311                      ((ctx->Stencil.WriteMask[0] & 0xff) << 24)); 
312
313    if ( rmesa->setup.sten_ref_mask_c != refmask ) {
314       rmesa->setup.sten_ref_mask_c = refmask;
315       rmesa->dirty |= R128_UPLOAD_MASKS;
316    }
317 }
318
319 static void r128DDStencilOpSeparate( struct gl_context *ctx, GLenum face, GLenum fail,
320                                      GLenum zfail, GLenum zpass )
321 {
322    r128ContextPtr rmesa = R128_CONTEXT(ctx);
323    GLuint z = rmesa->setup.z_sten_cntl_c;
324
325    if (!( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ))
326       return;
327
328    z &= ~(R128_STENCIL_S_FAIL_MASK | R128_STENCIL_ZPASS_MASK |
329           R128_STENCIL_ZFAIL_MASK);
330
331    switch ( ctx->Stencil.FailFunc[0] ) {
332    case GL_KEEP:
333       z |= R128_STENCIL_S_FAIL_KEEP;
334       break;
335    case GL_ZERO:
336       z |= R128_STENCIL_S_FAIL_ZERO;
337       break;
338    case GL_REPLACE:
339       z |= R128_STENCIL_S_FAIL_REPLACE;
340       break;
341    case GL_INCR:
342       z |= R128_STENCIL_S_FAIL_INC;
343       break;
344    case GL_DECR:
345       z |= R128_STENCIL_S_FAIL_DEC;
346       break;
347    case GL_INVERT:
348       z |= R128_STENCIL_S_FAIL_INV;
349       break;
350    case GL_INCR_WRAP:
351       z |= R128_STENCIL_S_FAIL_INC_WRAP;
352       break;
353    case GL_DECR_WRAP:
354       z |= R128_STENCIL_S_FAIL_DEC_WRAP;
355       break;
356    }
357
358    switch ( ctx->Stencil.ZFailFunc[0] ) {
359    case GL_KEEP:
360       z |= R128_STENCIL_ZFAIL_KEEP;
361       break;
362    case GL_ZERO:
363       z |= R128_STENCIL_ZFAIL_ZERO;
364       break;
365    case GL_REPLACE:
366       z |= R128_STENCIL_ZFAIL_REPLACE;
367       break;
368    case GL_INCR:
369       z |= R128_STENCIL_ZFAIL_INC;
370       break;
371    case GL_DECR:
372       z |= R128_STENCIL_ZFAIL_DEC;
373       break;
374    case GL_INVERT:
375       z |= R128_STENCIL_ZFAIL_INV;
376       break;
377    case GL_INCR_WRAP:
378       z |= R128_STENCIL_ZFAIL_INC_WRAP;
379       break;
380    case GL_DECR_WRAP:
381       z |= R128_STENCIL_ZFAIL_DEC_WRAP;
382       break;
383    }
384
385    switch ( ctx->Stencil.ZPassFunc[0] ) {
386    case GL_KEEP:
387       z |= R128_STENCIL_ZPASS_KEEP;
388       break;
389    case GL_ZERO:
390       z |= R128_STENCIL_ZPASS_ZERO;
391       break;
392    case GL_REPLACE:
393       z |= R128_STENCIL_ZPASS_REPLACE;
394       break;
395    case GL_INCR:
396       z |= R128_STENCIL_ZPASS_INC;
397       break;
398    case GL_DECR:
399       z |= R128_STENCIL_ZPASS_DEC;
400       break;
401    case GL_INVERT:
402       z |= R128_STENCIL_ZPASS_INV;
403       break;
404    case GL_INCR_WRAP:
405       z |= R128_STENCIL_ZPASS_INC_WRAP;
406       break;
407    case GL_DECR_WRAP:
408       z |= R128_STENCIL_ZPASS_DEC_WRAP;
409       break;
410    }
411
412    if ( rmesa->setup.z_sten_cntl_c != z ) {
413       rmesa->setup.z_sten_cntl_c = z;
414       rmesa->dirty |= R128_UPLOAD_CONTEXT;
415    }
416 }
417
418 static void r128DDClearStencil( struct gl_context *ctx, GLint s )
419 {
420    r128ContextPtr rmesa = R128_CONTEXT(ctx);
421
422    if (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) {
423       rmesa->ClearDepth &= 0x00ffffff;
424       rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
425    }
426 }
427
428 /* =============================================================
429  * Depth testing
430  */
431
432 static void r128UpdateZMode( struct gl_context *ctx )
433 {
434    r128ContextPtr rmesa = R128_CONTEXT(ctx);
435    GLuint z = rmesa->setup.z_sten_cntl_c;
436    GLuint t = rmesa->setup.tex_cntl_c;
437
438    if ( ctx->Depth.Test ) {
439       z &= ~R128_Z_TEST_MASK;
440
441       switch ( ctx->Depth.Func ) {
442       case GL_NEVER:
443          z |= R128_Z_TEST_NEVER;
444          break;
445       case GL_ALWAYS:
446          z |= R128_Z_TEST_ALWAYS;
447          break;
448       case GL_LESS:
449          z |= R128_Z_TEST_LESS;
450          break;
451       case GL_LEQUAL:
452          z |= R128_Z_TEST_LESSEQUAL;
453          break;
454       case GL_EQUAL:
455          z |= R128_Z_TEST_EQUAL;
456          break;
457       case GL_GEQUAL:
458          z |= R128_Z_TEST_GREATEREQUAL;
459          break;
460       case GL_GREATER:
461          z |= R128_Z_TEST_GREATER;
462          break;
463       case GL_NOTEQUAL:
464          z |= R128_Z_TEST_NEQUAL;
465          break;
466       }
467
468       t |=  R128_Z_ENABLE;
469    } else {
470       t &= ~R128_Z_ENABLE;
471    }
472
473    if ( ctx->Depth.Mask ) {
474       t |=  R128_Z_WRITE_ENABLE;
475    } else {
476       t &= ~R128_Z_WRITE_ENABLE;
477    }
478
479    if ( rmesa->setup.z_sten_cntl_c != z ) {
480       rmesa->setup.z_sten_cntl_c = z;
481       rmesa->dirty |= R128_UPLOAD_CONTEXT;
482    }
483    if ( rmesa->setup.tex_cntl_c != t ) {
484       rmesa->setup.tex_cntl_c = t;
485       rmesa->dirty |= R128_UPLOAD_CONTEXT;
486    }
487 }
488
489 static void r128DDDepthFunc( struct gl_context *ctx, GLenum func )
490 {
491    r128ContextPtr rmesa = R128_CONTEXT(ctx);
492
493    FLUSH_BATCH( rmesa );
494    rmesa->new_state |= R128_NEW_DEPTH;
495 }
496
497 static void r128DDDepthMask( struct gl_context *ctx, GLboolean flag )
498 {
499    r128ContextPtr rmesa = R128_CONTEXT(ctx);
500
501    FLUSH_BATCH( rmesa );
502    rmesa->new_state |= R128_NEW_DEPTH;
503 }
504
505 static void r128DDClearDepth( struct gl_context *ctx, GLclampd d )
506 {
507    r128ContextPtr rmesa = R128_CONTEXT(ctx);
508
509    switch ( rmesa->setup.z_sten_cntl_c &  R128_Z_PIX_WIDTH_MASK ) {
510    case R128_Z_PIX_WIDTH_16:
511       rmesa->ClearDepth = d * 0x0000ffff;
512       break;
513    case R128_Z_PIX_WIDTH_24:
514       rmesa->ClearDepth = d * 0x00ffffff;
515       rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
516       break;
517    case R128_Z_PIX_WIDTH_32:
518       rmesa->ClearDepth = d * 0xffffffff;
519       break;
520    }
521 }
522
523
524 /* =============================================================
525  * Fog
526  */
527
528 static void r128UpdateFogAttrib( struct gl_context *ctx )
529 {
530    r128ContextPtr rmesa = R128_CONTEXT(ctx);
531    GLuint t = rmesa->setup.tex_cntl_c;
532    GLubyte c[4];
533    GLuint col;
534
535    if ( ctx->Fog.Enabled ) {
536       t |=  R128_FOG_ENABLE;
537    } else {
538       t &= ~R128_FOG_ENABLE;
539    }
540
541    c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] );
542    c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] );
543    c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] );
544
545    col = r128PackColor( 4, c[0], c[1], c[2], 0 );
546
547    if ( rmesa->setup.fog_color_c != col ) {
548       rmesa->setup.fog_color_c = col;
549       rmesa->dirty |= R128_UPLOAD_CONTEXT;
550    }
551    if ( rmesa->setup.tex_cntl_c != t ) {
552       rmesa->setup.tex_cntl_c = t;
553       rmesa->dirty |= R128_UPLOAD_CONTEXT;
554    }
555 }
556
557 static void r128DDFogfv( struct gl_context *ctx, GLenum pname, const GLfloat *param )
558 {
559    r128ContextPtr rmesa = R128_CONTEXT(ctx);
560
561    FLUSH_BATCH( rmesa );
562    rmesa->new_state |= R128_NEW_FOG;
563 }
564
565
566 /* =============================================================
567  * Clipping
568  */
569
570 static void r128UpdateClipping( struct gl_context *ctx )
571 {
572    r128ContextPtr rmesa = R128_CONTEXT(ctx);
573
574    if ( rmesa->driDrawable ) {
575       __DRIdrawable *drawable = rmesa->driDrawable;
576       int x1 = 0;
577       int y1 = 0;
578       int x2 = drawable->w - 1;
579       int y2 = drawable->h - 1;
580
581       if ( ctx->Scissor.Enabled ) {
582          if ( ctx->Scissor.X > x1 ) {
583             x1 = ctx->Scissor.X;
584          }
585          if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) {
586             y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height;
587          }
588          if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) {
589             x2 = ctx->Scissor.X + ctx->Scissor.Width - 1;
590          }
591          if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) {
592             y2 = drawable->h - ctx->Scissor.Y - 1;
593          }
594       }
595
596       x1 += drawable->x;
597       y1 += drawable->y;
598       x2 += drawable->x;
599       y2 += drawable->y;
600
601       /* Clamp values to screen to avoid wrapping problems */
602       if ( x1 < 0 )
603          x1 = 0;
604       else if ( x1 >= rmesa->driScreen->fbWidth )
605          x1 = rmesa->driScreen->fbWidth - 1;
606       if ( y1 < 0 )
607          y1 = 0;
608       else if ( y1 >= rmesa->driScreen->fbHeight )
609          y1 = rmesa->driScreen->fbHeight - 1;
610       if ( x2 < 0 )
611          x2 = 0;
612       else if ( x2 >= rmesa->driScreen->fbWidth )
613          x2 = rmesa->driScreen->fbWidth - 1;
614       if ( y2 < 0 )
615          y2 = 0;
616       else if ( y2 >= rmesa->driScreen->fbHeight )
617          y2 = rmesa->driScreen->fbHeight - 1;
618
619       rmesa->setup.sc_top_left_c     = (((y1 & 0x3FFF) << 16) | (x1 & 0x3FFF));
620       rmesa->setup.sc_bottom_right_c = (((y2 & 0x3FFF) << 16) | (x2 & 0x3FFF));
621
622       rmesa->dirty |= R128_UPLOAD_CONTEXT;
623    }
624 }
625
626 static void r128DDScissor( struct gl_context *ctx,
627                            GLint x, GLint y, GLsizei w, GLsizei h )
628 {
629    r128ContextPtr rmesa = R128_CONTEXT(ctx);
630
631    FLUSH_BATCH( rmesa );
632    rmesa->new_state |= R128_NEW_CLIP;
633 }
634
635
636 /* =============================================================
637  * Culling
638  */
639
640 static void r128UpdateCull( struct gl_context *ctx )
641 {
642    r128ContextPtr rmesa = R128_CONTEXT(ctx);
643    GLuint f = rmesa->setup.pm4_vc_fpu_setup;
644
645    f &= ~R128_FRONT_DIR_MASK;
646
647    switch ( ctx->Polygon.FrontFace ) {
648    case GL_CW:
649       f |= R128_FRONT_DIR_CW;
650       break;
651    case GL_CCW:
652       f |= R128_FRONT_DIR_CCW;
653       break;
654    }
655
656    f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID;
657
658    if ( ctx->Polygon.CullFlag ) {
659       switch ( ctx->Polygon.CullFaceMode ) {
660       case GL_FRONT:
661          f &= ~R128_FRONTFACE_SOLID;
662          break;
663       case GL_BACK:
664          f &= ~R128_BACKFACE_SOLID;
665          break;
666       case GL_FRONT_AND_BACK:
667          f &= ~(R128_BACKFACE_SOLID |
668                 R128_FRONTFACE_SOLID);
669          break;
670       }
671    }
672
673    if ( 1 || rmesa->setup.pm4_vc_fpu_setup != f ) {
674       rmesa->setup.pm4_vc_fpu_setup = f;
675       rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP;
676    }
677 }
678
679 static void r128DDCullFace( struct gl_context *ctx, GLenum mode )
680 {
681    r128ContextPtr rmesa = R128_CONTEXT(ctx);
682
683    FLUSH_BATCH( rmesa );
684    rmesa->new_state |= R128_NEW_CULL;
685 }
686
687 static void r128DDFrontFace( struct gl_context *ctx, GLenum mode )
688 {
689    r128ContextPtr rmesa = R128_CONTEXT(ctx);
690
691    FLUSH_BATCH( rmesa );
692    rmesa->new_state |= R128_NEW_CULL;
693 }
694
695
696 /* =============================================================
697  * Masks
698  */
699
700 static void r128UpdateMasks( struct gl_context *ctx )
701 {
702    r128ContextPtr rmesa = R128_CONTEXT(ctx);
703
704    GLuint mask = r128PackColor( rmesa->r128Screen->cpp,
705                                 ctx->Color.ColorMask[0][RCOMP],
706                                 ctx->Color.ColorMask[0][GCOMP],
707                                 ctx->Color.ColorMask[0][BCOMP],
708                                 ctx->Color.ColorMask[0][ACOMP] );
709
710    if ( rmesa->setup.plane_3d_mask_c != mask ) {
711       rmesa->setup.plane_3d_mask_c = mask;
712       rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
713    }
714 }
715
716 static void r128DDColorMask( struct gl_context *ctx,
717                              GLboolean r, GLboolean g,
718                              GLboolean b, GLboolean a )
719 {
720    r128ContextPtr rmesa = R128_CONTEXT(ctx);
721
722    FLUSH_BATCH( rmesa );
723    rmesa->new_state |= R128_NEW_MASKS;
724 }
725
726
727 /* =============================================================
728  * Rendering attributes
729  *
730  * We really don't want to recalculate all this every time we bind a
731  * texture.  These things shouldn't change all that often, so it makes
732  * sense to break them out of the core texture state update routines.
733  */
734
735 static void updateSpecularLighting( struct gl_context *ctx )
736 {
737    r128ContextPtr rmesa = R128_CONTEXT(ctx);
738    GLuint t = rmesa->setup.tex_cntl_c;
739
740    if ( _mesa_need_secondary_color( ctx ) ) {
741       if (ctx->Light.ShadeModel == GL_FLAT) {
742          /* R128 can't do flat-shaded separate specular */
743          t &= ~R128_SPEC_LIGHT_ENABLE;
744          FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE );
745       }
746       else {
747          t |= R128_SPEC_LIGHT_ENABLE;
748          FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
749       }
750    }
751    else {
752       t &= ~R128_SPEC_LIGHT_ENABLE;
753       FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE );
754    }
755
756    if ( rmesa->setup.tex_cntl_c != t ) {
757       rmesa->setup.tex_cntl_c = t;
758       rmesa->dirty |= R128_UPLOAD_CONTEXT;
759       rmesa->dirty |= R128_UPLOAD_SETUP;
760       rmesa->new_state |= R128_NEW_CONTEXT;
761    }
762 }
763
764
765 static void r128DDLightModelfv( struct gl_context *ctx, GLenum pname,
766                                 const GLfloat *param )
767 {
768    r128ContextPtr rmesa = R128_CONTEXT(ctx);
769
770    if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) {
771       FLUSH_BATCH( rmesa );
772       updateSpecularLighting(ctx);
773    }
774
775    if ( pname == GL_LIGHT_MODEL_TWO_SIDE ) {
776       FLUSH_BATCH( rmesa );
777       r128ChooseRenderState( ctx );
778    }
779 }
780
781 static void r128DDShadeModel( struct gl_context *ctx, GLenum mode )
782 {
783    r128ContextPtr rmesa = R128_CONTEXT(ctx);
784    GLuint s = rmesa->setup.pm4_vc_fpu_setup;
785
786    s &= ~R128_FPU_COLOR_MASK;
787
788    switch ( mode ) {
789    case GL_FLAT:
790       s |= R128_FPU_COLOR_FLAT;
791       break;
792    case GL_SMOOTH:
793       s |= R128_FPU_COLOR_GOURAUD;
794       break;
795    default:
796       return;
797    }
798
799    updateSpecularLighting(ctx);
800
801    if ( rmesa->setup.pm4_vc_fpu_setup != s ) {
802       FLUSH_BATCH( rmesa );
803       rmesa->setup.pm4_vc_fpu_setup = s;
804
805       rmesa->new_state |= R128_NEW_CONTEXT;
806       rmesa->dirty |= R128_UPLOAD_SETUP;
807    }
808 }
809
810
811 /* =============================================================
812  * Window position
813  */
814
815 static void r128UpdateWindow( struct gl_context *ctx )
816 {
817    r128ContextPtr rmesa = R128_CONTEXT(ctx);
818    int x = rmesa->driDrawable->x;
819    int y = rmesa->driDrawable->y;
820    struct gl_renderbuffer *rb = ctx->DrawBuffer->_ColorDrawBuffers[0];
821    driRenderbuffer *drb = (driRenderbuffer *) rb;
822
823    rmesa->setup.window_xy_offset = (((y & 0xFFF) << R128_WINDOW_Y_SHIFT) |
824                                     ((x & 0xFFF) << R128_WINDOW_X_SHIFT));
825
826    rmesa->setup.dst_pitch_offset_c = (((drb->flippedPitch/8) << 21) |
827                                       (drb->flippedOffset >> 5));
828
829
830    rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW;
831 }
832
833
834 /* =============================================================
835  * Viewport
836  */
837
838 static void r128CalcViewport( struct gl_context *ctx )
839 {
840    r128ContextPtr rmesa = R128_CONTEXT(ctx);
841    const GLfloat *v = ctx->Viewport._WindowMap.m;
842    GLfloat *m = rmesa->hw_viewport;
843
844    /* See also r128_translate_vertex.
845     */
846    m[MAT_SX] =   v[MAT_SX];
847    m[MAT_TX] =   v[MAT_TX] + SUBPIXEL_X;
848    m[MAT_SY] = - v[MAT_SY];
849    m[MAT_TY] = - v[MAT_TY] + rmesa->driDrawable->h + SUBPIXEL_Y;
850    m[MAT_SZ] =   v[MAT_SZ] * rmesa->depth_scale;
851    m[MAT_TZ] =   v[MAT_TZ] * rmesa->depth_scale;
852 }
853
854 static void r128Viewport( struct gl_context *ctx,
855                           GLint x, GLint y,
856                           GLsizei width, GLsizei height )
857 {
858    r128CalcViewport( ctx );
859 }
860
861 static void r128DepthRange( struct gl_context *ctx,
862                             GLclampd nearval, GLclampd farval )
863 {
864    r128CalcViewport( ctx );
865 }
866
867
868 /* =============================================================
869  * Miscellaneous
870  */
871
872 static void r128DDClearColor( struct gl_context *ctx,
873                               const GLfloat color[4] )
874 {
875    r128ContextPtr rmesa = R128_CONTEXT(ctx);
876    GLubyte c[4];
877
878    CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
879    CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
880    CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
881    CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
882
883    rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp,
884                                       c[0], c[1], c[2], c[3] );
885 }
886
887 static void r128DDLogicOpCode( struct gl_context *ctx, GLenum opcode )
888 {
889    r128ContextPtr rmesa = R128_CONTEXT(ctx);
890
891    if ( ctx->Color.ColorLogicOpEnabled ) {
892       FLUSH_BATCH( rmesa );
893
894       FALLBACK( rmesa, R128_FALLBACK_LOGICOP, opcode != GL_COPY );
895    }
896 }
897
898 static void r128DDDrawBuffer( struct gl_context *ctx, GLenum mode )
899 {
900    r128ContextPtr rmesa = R128_CONTEXT(ctx);
901
902    FLUSH_BATCH( rmesa );
903
904    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
905       /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
906       FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
907       return;
908    }
909    else {
910       switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
911       case BUFFER_FRONT_LEFT:
912       case BUFFER_BACK_LEFT:
913          FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE );
914          break;
915       default:
916          /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */
917          FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE );
918          break;
919       }
920    }
921
922    rmesa->new_state |= R128_NEW_WINDOW;
923 }
924
925 static void r128DDReadBuffer( struct gl_context *ctx, GLenum mode )
926 {
927    /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
928 }
929
930
931 /* =============================================================
932  * Polygon stipple
933  */
934
935 static void r128DDPolygonStipple( struct gl_context *ctx, const GLubyte *mask )
936 {
937    r128ContextPtr rmesa = R128_CONTEXT(ctx);
938    GLuint stipple[32], i;
939    drm_r128_stipple_t stippleRec;
940
941    for (i = 0; i < 32; i++) {
942       stipple[31 - i] = ((mask[i*4+0] << 24) |
943                          (mask[i*4+1] << 16) |
944                          (mask[i*4+2] << 8)  |
945                          (mask[i*4+3]));
946    }
947
948    FLUSH_BATCH( rmesa );
949    LOCK_HARDWARE( rmesa );
950
951    stippleRec.mask = stipple;
952    drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE, 
953                     &stippleRec, sizeof(stippleRec) );
954
955    UNLOCK_HARDWARE( rmesa );
956
957    rmesa->new_state |= R128_NEW_CONTEXT;
958    rmesa->dirty |= R128_UPLOAD_CONTEXT;
959 }
960
961
962 /* =============================================================
963  * Render mode
964  */
965
966 static void r128DDRenderMode( struct gl_context *ctx, GLenum mode )
967 {
968    r128ContextPtr rmesa = R128_CONTEXT(ctx);
969    FALLBACK( rmesa, R128_FALLBACK_RENDER_MODE, (mode != GL_RENDER) );
970 }
971
972
973
974 /* =============================================================
975  * State enable/disable
976  */
977
978 static void r128DDEnable( struct gl_context *ctx, GLenum cap, GLboolean state )
979 {
980    r128ContextPtr rmesa = R128_CONTEXT(ctx);
981
982    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
983       fprintf( stderr, "%s( %s = %s )\n",
984                __FUNCTION__, _mesa_lookup_enum_by_nr( cap ),
985                state ? "GL_TRUE" : "GL_FALSE" );
986    }
987
988    switch ( cap ) {
989    case GL_ALPHA_TEST:
990       FLUSH_BATCH( rmesa );
991       rmesa->new_state |= R128_NEW_ALPHA;
992       break;
993
994    case GL_BLEND:
995       FLUSH_BATCH( rmesa );
996       rmesa->new_state |= R128_NEW_ALPHA;
997
998       /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
999        */
1000       FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
1001                 (ctx->Color.ColorLogicOpEnabled &&
1002                  ctx->Color.LogicOp != GL_COPY));
1003       break;
1004
1005    case GL_CULL_FACE:
1006       FLUSH_BATCH( rmesa );
1007       rmesa->new_state |= R128_NEW_CULL;
1008       break;
1009
1010    case GL_DEPTH_TEST:
1011       FLUSH_BATCH( rmesa );
1012       rmesa->new_state |= R128_NEW_DEPTH;
1013       break;
1014
1015    case GL_DITHER:
1016       do {
1017          GLuint t = rmesa->setup.tex_cntl_c;
1018          FLUSH_BATCH( rmesa );
1019
1020          if ( ctx->Color.DitherFlag ) {
1021             t |=  R128_DITHER_ENABLE;
1022          } else {
1023             t &= ~R128_DITHER_ENABLE;
1024          }
1025
1026          if ( rmesa->setup.tex_cntl_c != t ) {
1027             rmesa->setup.tex_cntl_c = t;
1028             rmesa->dirty |= R128_UPLOAD_CONTEXT;
1029          }
1030       } while (0);
1031       break;
1032
1033    case GL_FOG:
1034       FLUSH_BATCH( rmesa );
1035       rmesa->new_state |= R128_NEW_FOG;
1036       break;
1037
1038    case GL_COLOR_LOGIC_OP:
1039       FLUSH_BATCH( rmesa );
1040       FALLBACK( rmesa, R128_FALLBACK_LOGICOP,
1041                 state && ctx->Color.LogicOp != GL_COPY );
1042       break;
1043
1044    case GL_LIGHTING:
1045    case GL_COLOR_SUM_EXT:
1046       updateSpecularLighting(ctx);
1047       break;
1048
1049    case GL_SCISSOR_TEST:
1050       FLUSH_BATCH( rmesa );
1051       rmesa->scissor = state;
1052       rmesa->new_state |= R128_NEW_CLIP;
1053       break;
1054
1055    case GL_STENCIL_TEST:
1056       FLUSH_BATCH( rmesa );
1057       if ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ) {
1058          if ( state ) {
1059             rmesa->setup.tex_cntl_c |=  R128_STENCIL_ENABLE;
1060             /* Reset the fallback (if any) for bad stencil funcs */
1061             r128DDStencilOpSeparate( ctx, 0, ctx->Stencil.FailFunc[0],
1062                                      ctx->Stencil.ZFailFunc[0],
1063                                      ctx->Stencil.ZPassFunc[0] );
1064          } else {
1065             rmesa->setup.tex_cntl_c &= ~R128_STENCIL_ENABLE;
1066             FALLBACK( rmesa, R128_FALLBACK_STENCIL, GL_FALSE );
1067          }
1068          rmesa->dirty |= R128_UPLOAD_CONTEXT;
1069       } else {
1070          FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
1071       }
1072       break;
1073
1074    case GL_TEXTURE_1D:
1075    case GL_TEXTURE_2D:
1076    case GL_TEXTURE_3D:
1077       FLUSH_BATCH( rmesa );
1078       break;
1079
1080    case GL_POLYGON_STIPPLE:
1081       if ( rmesa->render_primitive == GL_TRIANGLES ) {
1082          FLUSH_BATCH( rmesa );
1083          rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE;
1084          if ( state ) {
1085             rmesa->setup.dp_gui_master_cntl_c |=
1086                R128_GMC_BRUSH_32x32_MONO_FG_LA;
1087          } else {
1088             rmesa->setup.dp_gui_master_cntl_c |=
1089                R128_GMC_BRUSH_SOLID_COLOR;
1090          }
1091          rmesa->new_state |= R128_NEW_CONTEXT;
1092          rmesa->dirty |= R128_UPLOAD_CONTEXT;
1093       }
1094       break;
1095
1096    default:
1097       return;
1098    }
1099 }
1100
1101
1102 /* =============================================================
1103  * State initialization, management
1104  */
1105
1106 static void r128DDPrintDirty( const char *msg, GLuint state )
1107 {
1108    fprintf( stderr,
1109             "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
1110             msg,
1111             state,
1112             (state & R128_UPLOAD_CORE)          ? "core, " : "",
1113             (state & R128_UPLOAD_CONTEXT)       ? "context, " : "",
1114             (state & R128_UPLOAD_SETUP)         ? "setup, " : "",
1115             (state & R128_UPLOAD_TEX0)          ? "tex0, " : "",
1116             (state & R128_UPLOAD_TEX1)          ? "tex1, " : "",
1117             (state & R128_UPLOAD_MASKS)         ? "masks, " : "",
1118             (state & R128_UPLOAD_WINDOW)        ? "window, " : "",
1119             (state & R128_UPLOAD_CLIPRECTS)     ? "cliprects, " : "",
1120             (state & R128_REQUIRE_QUIESCENCE)   ? "quiescence, " : "" );
1121 }
1122
1123 /*
1124  * Load the current context's state into the hardware.
1125  *
1126  * NOTE: Be VERY careful about ensuring the context state is marked for
1127  * upload, the only place it shouldn't be uploaded is when the setup
1128  * state has changed in ReducedPrimitiveChange as this comes right after
1129  * a state update.
1130  *
1131  * Blits of any type should always upload the context and masks after
1132  * they are done.
1133  */
1134 void r128EmitHwStateLocked( r128ContextPtr rmesa )
1135 {
1136    drm_r128_sarea_t *sarea = rmesa->sarea;
1137    drm_r128_context_regs_t *regs = &(rmesa->setup);
1138    const r128TexObjPtr t0 = rmesa->CurrentTexObj[0];
1139    const r128TexObjPtr t1 = rmesa->CurrentTexObj[1];
1140
1141    if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) {
1142       r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty );
1143    }
1144
1145    if ( rmesa->dirty & (R128_UPLOAD_CONTEXT |
1146                         R128_UPLOAD_SETUP |
1147                         R128_UPLOAD_MASKS |
1148                         R128_UPLOAD_WINDOW |
1149                         R128_UPLOAD_CORE) ) {
1150       memcpy( &sarea->context_state, regs, sizeof(sarea->context_state) );
1151       
1152       if( rmesa->dirty & R128_UPLOAD_CONTEXT )
1153       {
1154          /* One possible side-effect of uploading a new context is the
1155           * setting of the R128_GMC_AUX_CLIP_DIS bit, which causes all
1156           * auxilliary cliprects to be disabled. So the next command must
1157           * upload them again. */
1158          rmesa->dirty |= R128_UPLOAD_CLIPRECTS;
1159       }
1160    }
1161
1162    if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) {
1163       drm_r128_texture_regs_t *tex = &sarea->tex_state[0];
1164
1165       tex->tex_cntl             = t0->setup.tex_cntl;
1166       tex->tex_combine_cntl     = rmesa->tex_combine[0];
1167       tex->tex_size_pitch       = t0->setup.tex_size_pitch;
1168       memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0],
1169               sizeof(tex->tex_offset ) );
1170       tex->tex_border_color     = t0->setup.tex_border_color;
1171    }
1172
1173    if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) {
1174       drm_r128_texture_regs_t *tex = &sarea->tex_state[1];
1175
1176       tex->tex_cntl             = t1->setup.tex_cntl;
1177       tex->tex_combine_cntl     = rmesa->tex_combine[1];
1178       tex->tex_size_pitch       = t1->setup.tex_size_pitch;
1179       memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0],
1180               sizeof(tex->tex_offset ) );
1181       tex->tex_border_color     = t1->setup.tex_border_color;
1182    }
1183
1184    sarea->vertsize = rmesa->vertex_size;
1185    sarea->vc_format = rmesa->vertex_format;
1186
1187    /* Turn off the texture cache flushing */
1188    rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
1189
1190    sarea->dirty |= rmesa->dirty;
1191    rmesa->dirty &= R128_UPLOAD_CLIPRECTS;
1192 }
1193
1194 static void r128DDPrintState( const char *msg, GLuint flags )
1195 {
1196    fprintf( stderr,
1197             "%s: (0x%x) %s%s%s%s%s%s%s%s\n",
1198             msg,
1199             flags,
1200             (flags & R128_NEW_CONTEXT)  ? "context, " : "",
1201             (flags & R128_NEW_ALPHA)    ? "alpha, " : "",
1202             (flags & R128_NEW_DEPTH)    ? "depth, " : "",
1203             (flags & R128_NEW_FOG)      ? "fog, " : "",
1204             (flags & R128_NEW_CLIP)     ? "clip, " : "",
1205             (flags & R128_NEW_CULL)     ? "cull, " : "",
1206             (flags & R128_NEW_MASKS)    ? "masks, " : "",
1207             (flags & R128_NEW_WINDOW)   ? "window, " : "" );
1208 }
1209
1210 void r128DDUpdateHWState( struct gl_context *ctx )
1211 {
1212    r128ContextPtr rmesa = R128_CONTEXT(ctx);
1213    int new_state = rmesa->new_state;
1214
1215    if ( new_state || rmesa->NewGLState & _NEW_TEXTURE )
1216    {
1217       FLUSH_BATCH( rmesa );
1218
1219       rmesa->new_state = 0;
1220
1221       if ( R128_DEBUG & DEBUG_VERBOSE_MSG )
1222          r128DDPrintState( "r128UpdateHwState", new_state );
1223
1224       /* Update the various parts of the context's state.
1225        */
1226       if ( new_state & R128_NEW_ALPHA )
1227          r128UpdateAlphaMode( ctx );
1228
1229       if ( new_state & R128_NEW_DEPTH )
1230          r128UpdateZMode( ctx );
1231
1232       if ( new_state & R128_NEW_FOG )
1233          r128UpdateFogAttrib( ctx );
1234
1235       if ( new_state & R128_NEW_CLIP )
1236          r128UpdateClipping( ctx );
1237
1238       if ( new_state & R128_NEW_CULL )
1239          r128UpdateCull( ctx );
1240
1241       if ( new_state & R128_NEW_MASKS )
1242          r128UpdateMasks( ctx );
1243
1244       if ( new_state & R128_NEW_WINDOW )
1245       {
1246          r128UpdateWindow( ctx );
1247          r128CalcViewport( ctx );
1248       }
1249
1250       if ( rmesa->NewGLState & _NEW_TEXTURE ) {
1251          r128UpdateTextureState( ctx );
1252       }
1253    }
1254 }
1255
1256
1257 static void r128DDInvalidateState( struct gl_context *ctx, GLuint new_state )
1258 {
1259    _swrast_InvalidateState( ctx, new_state );
1260    _swsetup_InvalidateState( ctx, new_state );
1261    _vbo_InvalidateState( ctx, new_state );
1262    _tnl_InvalidateState( ctx, new_state );
1263    R128_CONTEXT(ctx)->NewGLState |= new_state;
1264 }
1265
1266
1267
1268 /* Initialize the context's hardware state.
1269  */
1270 void r128DDInitState( r128ContextPtr rmesa )
1271 {
1272    int dst_bpp, depth_bpp;
1273
1274    switch ( rmesa->r128Screen->cpp ) {
1275    case 2:
1276       dst_bpp = R128_GMC_DST_16BPP;
1277       break;
1278    case 4:
1279       dst_bpp = R128_GMC_DST_32BPP;
1280       break;
1281    default:
1282       fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" );
1283       exit( -1 );
1284    }
1285
1286    rmesa->ClearColor = 0x00000000;
1287
1288    switch ( rmesa->glCtx->Visual.depthBits ) {
1289    case 16:
1290       rmesa->ClearDepth = 0x0000ffff;
1291       depth_bpp = R128_Z_PIX_WIDTH_16;
1292       rmesa->depth_scale = 1.0 / (GLfloat)0xffff;
1293       break;
1294    case 24:
1295       rmesa->ClearDepth = 0x00ffffff;
1296       depth_bpp = R128_Z_PIX_WIDTH_24;
1297       rmesa->depth_scale = 1.0 / (GLfloat)0xffffff;
1298       break;
1299    default:
1300       fprintf( stderr, "Error: Unsupported depth %d... exiting\n",
1301                rmesa->glCtx->Visual.depthBits );
1302       exit( -1 );
1303    }
1304
1305    rmesa->Fallback = 0;
1306
1307    /* Hardware state:
1308     */
1309    rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL |
1310                                         R128_GMC_DST_CLIPPING |
1311                                         R128_GMC_BRUSH_SOLID_COLOR |
1312                                         dst_bpp |
1313                                         R128_GMC_SRC_DATATYPE_COLOR |
1314                                         R128_GMC_BYTE_MSB_TO_LSB |
1315                                         R128_GMC_CONVERSION_TEMP_6500 |
1316                                         R128_ROP3_S |
1317                                         R128_DP_SRC_SOURCE_MEMORY |
1318                                         R128_GMC_3D_FCN_EN |
1319                                         R128_GMC_CLR_CMP_CNTL_DIS |
1320                                         R128_GMC_AUX_CLIP_DIS |
1321                                         R128_GMC_WR_MSK_DIS);
1322
1323    rmesa->setup.sc_top_left_c     = 0x00000000;
1324    rmesa->setup.sc_bottom_right_c = 0x1fff1fff;
1325
1326    rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset;
1327    rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) |
1328                              R128_Z_TILE);
1329
1330    rmesa->setup.z_sten_cntl_c = (depth_bpp |
1331                                  R128_Z_TEST_LESS |
1332                                  R128_STENCIL_TEST_ALWAYS |
1333                                  R128_STENCIL_S_FAIL_KEEP |
1334                                  R128_STENCIL_ZPASS_KEEP |
1335                                  R128_STENCIL_ZFAIL_KEEP);
1336
1337    rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE |
1338                               R128_SHADE_ENABLE |
1339                               R128_DITHER_ENABLE |
1340                               R128_ALPHA_IN_TEX_COMPLETE_A |
1341                               R128_LIGHT_DIS |
1342                               R128_ALPHA_LIGHT_DIS |
1343                               R128_TEX_CACHE_FLUSH |
1344                               (0x3f << R128_LOD_BIAS_SHIFT));
1345
1346    rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE |
1347                                           R128_MISC_SCALE_PIX_REPLICATE |
1348                                           R128_ALPHA_COMB_ADD_CLAMP |
1349                                           R128_FOG_VERTEX |
1350                                           (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1351                                           (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1352                                           R128_ALPHA_TEST_ALWAYS);
1353
1354    rmesa->setup.texture_clr_cmp_clr_c = 0x00000000;
1355    rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff;
1356
1357    rmesa->setup.fog_color_c = 0x00000000;
1358
1359    rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW |
1360                                     R128_BACKFACE_SOLID |
1361                                     R128_FRONTFACE_SOLID |
1362                                     R128_FPU_COLOR_GOURAUD |
1363                                     R128_FPU_SUB_PIX_4BITS |
1364                                     R128_FPU_MODE_3D |
1365                                     R128_TRAP_BITS_DISABLE |
1366                                     R128_XFACTOR_2 |
1367                                     R128_YFACTOR_2 |
1368                                     R128_FLAT_SHADE_VERTEX_OGL |
1369                                     R128_FPU_ROUND_TRUNCATE |
1370                                     R128_WM_SEL_8DW);
1371
1372    rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD |
1373                               R128_PRIM_TYPE_TRI |
1374                               R128_TEXTURE_ST_MULT_W |
1375                               R128_STARTING_VERTEX_1 |
1376                               R128_ENDING_VERTEX_3 |
1377                               R128_SU_POLY_LINE_NOT_LAST |
1378                               R128_SUB_PIX_4BITS);
1379
1380    rmesa->setup.tex_size_pitch_c = 0x00000000;
1381    rmesa->setup.constant_color_c = 0x00ffffff;
1382
1383    rmesa->setup.dp_write_mask   = 0xffffffff;
1384    rmesa->setup.sten_ref_mask_c = 0xffff0000;
1385    rmesa->setup.plane_3d_mask_c = 0xffffffff;
1386
1387    rmesa->setup.window_xy_offset = 0x00000000;
1388
1389    rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE |
1390                                  R128_TEX_CACHE_SIZE_FULL |
1391                                  R128_DITHER_INIT_RESET |
1392                                  R128_SCALE_3D_TEXMAP_SHADE |
1393                                  R128_SCALE_PIX_REPLICATE |
1394                                  R128_ALPHA_COMB_ADD_CLAMP |
1395                                  R128_FOG_VERTEX |
1396                                  (R128_ALPHA_BLEND_ONE << R128_ALPHA_BLEND_SRC_SHIFT) |
1397                                  (R128_ALPHA_BLEND_ZERO << R128_ALPHA_BLEND_DST_SHIFT) |
1398                                  R128_ALPHA_TEST_ALWAYS |
1399                                  R128_COMPOSITE_SHADOW_CMP_EQUAL |
1400                                  R128_TEX_MAP_ALPHA_IN_TEXTURE |
1401                                  R128_TEX_CACHE_LINE_SIZE_4QW);
1402
1403    rmesa->new_state = R128_NEW_ALL;
1404 }
1405
1406 /* Initialize the driver's state functions.
1407  */
1408 void r128DDInitStateFuncs( struct gl_context *ctx )
1409 {
1410    ctx->Driver.UpdateState              = r128DDInvalidateState;
1411
1412    ctx->Driver.ClearColor               = r128DDClearColor;
1413    ctx->Driver.ClearStencil             = r128DDClearStencil;
1414    ctx->Driver.DrawBuffer               = r128DDDrawBuffer;
1415    ctx->Driver.ReadBuffer               = r128DDReadBuffer;
1416
1417    ctx->Driver.ColorMask                = r128DDColorMask;
1418    ctx->Driver.AlphaFunc                = r128DDAlphaFunc;
1419    ctx->Driver.BlendEquationSeparate    = r128DDBlendEquationSeparate;
1420    ctx->Driver.BlendFuncSeparate        = r128DDBlendFuncSeparate;
1421    ctx->Driver.ClearDepth               = r128DDClearDepth;
1422    ctx->Driver.CullFace                 = r128DDCullFace;
1423    ctx->Driver.FrontFace                = r128DDFrontFace;
1424    ctx->Driver.DepthFunc                = r128DDDepthFunc;
1425    ctx->Driver.DepthMask                = r128DDDepthMask;
1426    ctx->Driver.Enable                   = r128DDEnable;
1427    ctx->Driver.Fogfv                    = r128DDFogfv;
1428    ctx->Driver.Hint                     = NULL;
1429    ctx->Driver.Lightfv                  = NULL;
1430    ctx->Driver.LightModelfv             = r128DDLightModelfv;
1431    ctx->Driver.LogicOpcode              = r128DDLogicOpCode;
1432    ctx->Driver.PolygonMode              = NULL;
1433    ctx->Driver.PolygonStipple           = r128DDPolygonStipple;
1434    ctx->Driver.RenderMode               = r128DDRenderMode;
1435    ctx->Driver.Scissor                  = r128DDScissor;
1436    ctx->Driver.ShadeModel               = r128DDShadeModel;
1437    ctx->Driver.StencilFuncSeparate      = r128DDStencilFuncSeparate;
1438    ctx->Driver.StencilMaskSeparate      = r128DDStencilMaskSeparate;
1439    ctx->Driver.StencilOpSeparate        = r128DDStencilOpSeparate;
1440
1441    ctx->Driver.DepthRange               = r128DepthRange;
1442    ctx->Driver.Viewport                 = r128Viewport;
1443 }