Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / drivers / dri / unichrome / via_state.c
1 /*
2  * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sub license,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22  * DEALINGS IN THE SOFTWARE.
23  */
24
25 #include <stdio.h>
26
27 #include "main/glheader.h"
28 #include "main/context.h"
29 #include "main/macros.h"
30 #include "main/colormac.h"
31 #include "main/enums.h"
32 #include "main/dd.h"
33 #include "main/mm.h"
34
35 #include "via_context.h"
36 #include "via_state.h"
37 #include "via_tex.h"
38 #include "via_ioctl.h"
39 #include "via_3d_reg.h"
40
41 #include "swrast/swrast.h"
42 #include "vbo/vbo.h"
43 #include "tnl/tnl.h"
44 #include "swrast_setup/swrast_setup.h"
45
46
47 static GLuint ROP[16] = {
48     HC_HROP_BLACK,    /* GL_CLEAR           0                           */
49     HC_HROP_DPa,      /* GL_AND             s & d                       */
50     HC_HROP_PDna,     /* GL_AND_REVERSE     s & ~d                      */
51     HC_HROP_P,        /* GL_COPY            s                           */
52     HC_HROP_DPna,     /* GL_AND_INVERTED    ~s & d                      */
53     HC_HROP_D,        /* GL_NOOP            d                           */
54     HC_HROP_DPx,      /* GL_XOR             s ^ d                       */
55     HC_HROP_DPo,      /* GL_OR              s | d                       */
56     HC_HROP_DPon,     /* GL_NOR             ~(s | d)                    */
57     HC_HROP_DPxn,     /* GL_EQUIV           ~(s ^ d)                    */
58     HC_HROP_Dn,       /* GL_INVERT          ~d                          */
59     HC_HROP_PDno,     /* GL_OR_REVERSE      s | ~d                      */
60     HC_HROP_Pn,       /* GL_COPY_INVERTED   ~s                          */
61     HC_HROP_DPno,     /* GL_OR_INVERTED     ~s | d                      */
62     HC_HROP_DPan,     /* GL_NAND            ~(s & d)                    */
63     HC_HROP_WHITE     /* GL_SET             1                           */
64 };
65
66 /*
67  * Compute the 'S5.5' lod bias factor from the floating point OpenGL bias.
68  */
69 static GLuint viaComputeLodBias(GLfloat bias)
70 {
71    int b = (int) (bias * 32.0);
72    if (b > 511)
73       b = 511;
74    else if (b < -512)
75       b = -512;
76    return (GLuint) b;
77 }
78
79 void viaEmitState(struct via_context *vmesa)
80 {
81    struct gl_context *ctx = vmesa->glCtx;
82    GLuint i = 0;
83    GLuint j = 0;
84    RING_VARS;
85
86    viaCheckDma(vmesa, 0x110);
87     
88    BEGIN_RING(5);
89    OUT_RING( HC_HEADER2 );
90    OUT_RING( (HC_ParaType_NotTex << 16) );
91    OUT_RING( ((HC_SubA_HEnable << 24) | vmesa->regEnable) );
92    OUT_RING( ((HC_SubA_HFBBMSKL << 24) | vmesa->regHFBBMSKL) );    
93    OUT_RING( ((HC_SubA_HROP << 24) | vmesa->regHROP) );        
94    ADVANCE_RING();
95     
96    if (vmesa->have_hw_stencil) {
97       GLuint pitch, format, offset;
98         
99       format = HC_HZWBFM_24;            
100       offset = vmesa->depth.offset;
101       pitch = vmesa->depth.pitch;
102         
103       BEGIN_RING(6);
104       OUT_RING( (HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF) );
105       OUT_RING( (HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24) );     
106       OUT_RING( (HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
107                  format | pitch );            
108       OUT_RING( (HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD );
109       OUT_RING( (HC_SubA_HSTREF << 24) | vmesa->regHSTREF );
110       OUT_RING( (HC_SubA_HSTMD << 24) | vmesa->regHSTMD );
111       ADVANCE_RING();
112    }
113    else if (vmesa->hasDepth) {
114       GLuint pitch, format, offset;
115         
116       if (vmesa->depthBits == 16) {
117          format = HC_HZWBFM_16;
118       }     
119       else {
120          format = HC_HZWBFM_32;
121       }
122             
123             
124       offset = vmesa->depth.offset;
125       pitch = vmesa->depth.pitch;
126         
127       BEGIN_RING(4);
128       OUT_RING( (HC_SubA_HZWBBasL << 24) | (offset & 0xFFFFFF) );
129       OUT_RING( (HC_SubA_HZWBBasH << 24) | ((offset & 0xFF000000) >> 24) );
130       OUT_RING( (HC_SubA_HZWBType << 24) | HC_HDBLoc_Local | HC_HZONEasFF_MASK |
131                  format | pitch );
132       OUT_RING( (HC_SubA_HZWTMD << 24) | vmesa->regHZWTMD );
133       ADVANCE_RING();
134    }
135     
136    if (ctx->Color.AlphaEnabled) {
137       BEGIN_RING(1);
138       OUT_RING( (HC_SubA_HATMD << 24) | vmesa->regHATMD );
139       ADVANCE_RING();
140       i++;
141    }   
142
143    if (ctx->Color.BlendEnabled) {
144       BEGIN_RING(11);
145       OUT_RING( (HC_SubA_HABLCsat << 24) | vmesa->regHABLCsat );
146       OUT_RING( (HC_SubA_HABLCop  << 24) | vmesa->regHABLCop ); 
147       OUT_RING( (HC_SubA_HABLAsat << 24) | vmesa->regHABLAsat );        
148       OUT_RING( (HC_SubA_HABLAop  << 24) | vmesa->regHABLAop ); 
149       OUT_RING( (HC_SubA_HABLRCa  << 24) | vmesa->regHABLRCa ); 
150       OUT_RING( (HC_SubA_HABLRFCa << 24) | vmesa->regHABLRFCa );        
151       OUT_RING( (HC_SubA_HABLRCbias << 24) | vmesa->regHABLRCbias ); 
152       OUT_RING( (HC_SubA_HABLRCb  << 24) | vmesa->regHABLRCb ); 
153       OUT_RING( (HC_SubA_HABLRFCb << 24) | vmesa->regHABLRFCb );        
154       OUT_RING( (HC_SubA_HABLRAa  << 24) | vmesa->regHABLRAa ); 
155       OUT_RING( (HC_SubA_HABLRAb  << 24) | vmesa->regHABLRAb ); 
156       ADVANCE_RING();
157    }
158     
159    if (ctx->Fog.Enabled) {
160       BEGIN_RING(3);
161       OUT_RING( (HC_SubA_HFogLF << 24) | vmesa->regHFogLF ); 
162       OUT_RING( (HC_SubA_HFogCL << 24) | vmesa->regHFogCL ); 
163       OUT_RING( (HC_SubA_HFogCH << 24) | vmesa->regHFogCH ); 
164       ADVANCE_RING();
165    }
166     
167    if (ctx->Line.StippleFlag) {
168       BEGIN_RING(2);
169       OUT_RING( (HC_SubA_HLP << 24) | ctx->Line.StipplePattern ); 
170       OUT_RING( (HC_SubA_HLPRF << 24) | ctx->Line.StippleFactor );
171       ADVANCE_RING();
172    }
173
174    BEGIN_RING(1);
175    OUT_RING( (HC_SubA_HPixGC << 24) | 0x0 ); 
176    ADVANCE_RING();
177     
178    QWORD_PAD_RING();
179
180
181    if (ctx->Texture._EnabledUnits) {
182     
183       struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
184       struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
185
186       {
187          GLuint nDummyValue = 0;
188
189          BEGIN_RING( 8 );
190          OUT_RING( HC_HEADER2 );
191          OUT_RING( (HC_ParaType_Tex << 16) | (HC_SubType_TexGeneral << 24) );
192
193          if (texUnit0->Enabled && texUnit1->Enabled) {
194             nDummyValue = (HC_SubA_HTXSMD << 24) | (1 << 3);                
195          }
196          else {
197             nDummyValue = (HC_SubA_HTXSMD << 24) | 0;
198          }
199
200          if (vmesa->clearTexCache) {
201             vmesa->clearTexCache = 0;
202             OUT_RING( nDummyValue | HC_HTXCHCLR_MASK );
203             OUT_RING( nDummyValue );
204          }
205          else {
206             OUT_RING( nDummyValue );
207             OUT_RING( nDummyValue );
208          }
209
210          OUT_RING( HC_HEADER2 );
211          OUT_RING( HC_ParaType_NotTex << 16 );
212          OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
213          OUT_RING( (HC_SubA_HEnable << 24) | vmesa->regEnable );
214          ADVANCE_RING();
215       }
216
217       if (texUnit0->Enabled) {
218          struct gl_texture_object *texObj = texUnit0->_Current;
219          struct via_texture_object *t = (struct via_texture_object *)texObj;
220          GLuint numLevels = t->lastLevel - t->firstLevel + 1;
221          if (VIA_DEBUG & DEBUG_STATE) {
222             fprintf(stderr, "texture0 enabled\n");
223          }              
224          if (numLevels == 8) {
225             BEGIN_RING(27);
226             OUT_RING( HC_HEADER2 );
227             OUT_RING( (HC_ParaType_Tex << 16) |  (0 << 24) );
228             OUT_RING( t->regTexFM );
229             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
230                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
231             OUT_RING( t->regTexWidthLog2[0] );
232             OUT_RING( t->regTexWidthLog2[1] );
233             OUT_RING( t->regTexHeightLog2[0] );
234             OUT_RING( t->regTexHeightLog2[1] );
235             OUT_RING( t->regTexBaseH[0] );
236             OUT_RING( t->regTexBaseH[1] );
237             OUT_RING( t->regTexBaseH[2] );
238             OUT_RING( t->regTexBaseAndPitch[0].baseL );
239             OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
240             OUT_RING( t->regTexBaseAndPitch[1].baseL );
241             OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
242             OUT_RING( t->regTexBaseAndPitch[2].baseL );
243             OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
244             OUT_RING( t->regTexBaseAndPitch[3].baseL );
245             OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
246             OUT_RING( t->regTexBaseAndPitch[4].baseL );
247             OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
248             OUT_RING( t->regTexBaseAndPitch[5].baseL );
249             OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
250             OUT_RING( t->regTexBaseAndPitch[6].baseL );
251             OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
252             OUT_RING( t->regTexBaseAndPitch[7].baseL );
253             OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
254             ADVANCE_RING();
255          }
256          else if (numLevels > 1) {
257
258             BEGIN_RING(12 + numLevels * 2);
259             OUT_RING( HC_HEADER2 );
260             OUT_RING( (HC_ParaType_Tex << 16) |  (0 << 24) );
261             OUT_RING( t->regTexFM );
262             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
263                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
264             OUT_RING( t->regTexWidthLog2[0] );
265             OUT_RING( t->regTexHeightLog2[0] );
266                 
267             if (numLevels > 6) {
268                OUT_RING( t->regTexWidthLog2[1] );
269                OUT_RING( t->regTexHeightLog2[1] );
270             }
271                 
272             OUT_RING( t->regTexBaseH[0] );
273                 
274             if (numLevels > 3) {
275                OUT_RING( t->regTexBaseH[1] );
276             }
277             if (numLevels > 6) {
278                OUT_RING( t->regTexBaseH[2] );
279             }
280             if (numLevels > 9)  {
281                OUT_RING( t->regTexBaseH[3] );
282             }
283
284             for (j = 0; j < numLevels; j++) {
285                OUT_RING( t->regTexBaseAndPitch[j].baseL );
286                OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
287             }
288
289             ADVANCE_RING_VARIABLE();
290          }
291          else {
292
293             BEGIN_RING(9);
294             OUT_RING( HC_HEADER2 );
295             OUT_RING( (HC_ParaType_Tex << 16) |  (0 << 24) );
296             OUT_RING( t->regTexFM );
297             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
298                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
299             OUT_RING( t->regTexWidthLog2[0] );
300             OUT_RING( t->regTexHeightLog2[0] );
301             OUT_RING( t->regTexBaseH[0] );
302             OUT_RING( t->regTexBaseAndPitch[0].baseL );
303             OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
304             ADVANCE_RING();
305          }
306
307          BEGIN_RING(14);
308          OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB[0] );
309          OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD[0] );
310          OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat[0] );
311          OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop[0] );
312          OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog[0] );
313          OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat[0] );
314          OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb[0] );
315          OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa[0] );
316          OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog[0] );
317          OUT_RING( (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa[0] );
318          OUT_RING( (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc[0] );
319          OUT_RING( (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias[0] );
320          OUT_RING( (HC_SubA_HTXnTBC << 24) | vmesa->regHTXnTBC[0] );
321          OUT_RING( (HC_SubA_HTXnTRAH << 24) | vmesa->regHTXnTRAH[0] );
322 /*       OUT_RING( (HC_SubA_HTXnCLODu << 24) | vmesa->regHTXnCLOD[0] ); */
323          ADVANCE_RING();
324
325          /* KW:  This test never succeeds:
326           */
327          if (t->regTexFM == HC_HTXnFM_Index8) {
328             const struct gl_color_table *table = &texObj->Palette;
329             const GLfloat *tableF = table->TableF;
330
331             BEGIN_RING(2 + table->Size);
332             OUT_RING( HC_HEADER2 );
333             OUT_RING( (HC_ParaType_Palette << 16) | (0 << 24) );
334             for (j = 0; j < table->Size; j++) 
335                OUT_RING( tableF[j] );
336             ADVANCE_RING();
337                
338          }
339
340          QWORD_PAD_RING();
341       }
342         
343       if (texUnit1->Enabled) {
344          struct gl_texture_object *texObj = texUnit1->_Current;
345          struct via_texture_object *t = (struct via_texture_object *)texObj;
346          GLuint numLevels = t->lastLevel - t->firstLevel + 1;
347          int texunit = (texUnit0->Enabled ? 1 : 0);
348          if (VIA_DEBUG & DEBUG_STATE) {
349             fprintf(stderr, "texture1 enabled\n");
350          }              
351          if (numLevels == 8) {
352             BEGIN_RING(27);
353             OUT_RING( HC_HEADER2 );
354             OUT_RING( (HC_ParaType_Tex << 16) |  (texunit << 24) );
355             OUT_RING( t->regTexFM );
356             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
357                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
358             OUT_RING( t->regTexWidthLog2[0] );
359             OUT_RING( t->regTexWidthLog2[1] );
360             OUT_RING( t->regTexHeightLog2[0] );
361             OUT_RING( t->regTexHeightLog2[1] );
362             OUT_RING( t->regTexBaseH[0] );
363             OUT_RING( t->regTexBaseH[1] );
364             OUT_RING( t->regTexBaseH[2] );
365             OUT_RING( t->regTexBaseAndPitch[0].baseL );
366             OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
367             OUT_RING( t->regTexBaseAndPitch[1].baseL );
368             OUT_RING( t->regTexBaseAndPitch[1].pitchLog2 );
369             OUT_RING( t->regTexBaseAndPitch[2].baseL );
370             OUT_RING( t->regTexBaseAndPitch[2].pitchLog2 );
371             OUT_RING( t->regTexBaseAndPitch[3].baseL );
372             OUT_RING( t->regTexBaseAndPitch[3].pitchLog2 );
373             OUT_RING( t->regTexBaseAndPitch[4].baseL );
374             OUT_RING( t->regTexBaseAndPitch[4].pitchLog2 );
375             OUT_RING( t->regTexBaseAndPitch[5].baseL );
376             OUT_RING( t->regTexBaseAndPitch[5].pitchLog2 );
377             OUT_RING( t->regTexBaseAndPitch[6].baseL );
378             OUT_RING( t->regTexBaseAndPitch[6].pitchLog2 );
379             OUT_RING( t->regTexBaseAndPitch[7].baseL );
380             OUT_RING( t->regTexBaseAndPitch[7].pitchLog2 );
381             ADVANCE_RING();
382          }
383          else if (numLevels > 1) {
384             BEGIN_RING(12 + numLevels * 2);
385             OUT_RING( HC_HEADER2 );
386             OUT_RING( (HC_ParaType_Tex << 16) |  (texunit << 24) );
387             OUT_RING( t->regTexFM );
388             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
389                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
390             OUT_RING( t->regTexWidthLog2[0] );
391             OUT_RING( t->regTexHeightLog2[0] );
392                 
393             if (numLevels > 6) {
394                OUT_RING( t->regTexWidthLog2[1] );
395                OUT_RING( t->regTexHeightLog2[1] );
396                i += 2;
397             }
398                 
399             OUT_RING( t->regTexBaseH[0] );
400                 
401             if (numLevels > 3) { 
402                OUT_RING( t->regTexBaseH[1] );
403             }
404             if (numLevels > 6) {
405                OUT_RING( t->regTexBaseH[2] );
406             }
407             if (numLevels > 9)  {
408                OUT_RING( t->regTexBaseH[3] );
409             }
410                 
411             for (j = 0; j < numLevels; j++) {
412                OUT_RING( t->regTexBaseAndPitch[j].baseL );
413                OUT_RING( t->regTexBaseAndPitch[j].pitchLog2 );
414             }
415             ADVANCE_RING_VARIABLE();
416          }
417          else {
418             BEGIN_RING(9);
419             OUT_RING( HC_HEADER2 );
420             OUT_RING( (HC_ParaType_Tex << 16) |  (texunit << 24) );
421             OUT_RING( t->regTexFM );
422             OUT_RING( (HC_SubA_HTXnL0OS << 24) |
423                ((t->lastLevel) << HC_HTXnLVmax_SHIFT) | t->firstLevel );
424             OUT_RING( t->regTexWidthLog2[0] );
425             OUT_RING( t->regTexHeightLog2[0] );
426             OUT_RING( t->regTexBaseH[0] );
427             OUT_RING( t->regTexBaseAndPitch[0].baseL );
428             OUT_RING( t->regTexBaseAndPitch[0].pitchLog2 );
429             ADVANCE_RING();
430          }
431
432          BEGIN_RING(14);
433          OUT_RING( (HC_SubA_HTXnTB << 24) | vmesa->regHTXnTB[1] );
434          OUT_RING( (HC_SubA_HTXnMPMD << 24) | vmesa->regHTXnMPMD[1] );
435          OUT_RING( (HC_SubA_HTXnTBLCsat << 24) | vmesa->regHTXnTBLCsat[1] );
436          OUT_RING( (HC_SubA_HTXnTBLCop << 24) | vmesa->regHTXnTBLCop[1] );
437          OUT_RING( (HC_SubA_HTXnTBLMPfog << 24) | vmesa->regHTXnTBLMPfog[1] );
438          OUT_RING( (HC_SubA_HTXnTBLAsat << 24) | vmesa->regHTXnTBLAsat[1] );
439          OUT_RING( (HC_SubA_HTXnTBLRCb << 24) | vmesa->regHTXnTBLRCb[1] );
440          OUT_RING( (HC_SubA_HTXnTBLRAa << 24) | vmesa->regHTXnTBLRAa[1] );
441          OUT_RING( (HC_SubA_HTXnTBLRFog << 24) | vmesa->regHTXnTBLRFog[1] );
442          OUT_RING( (HC_SubA_HTXnTBLRCa << 24) | vmesa->regHTXnTBLRCa[1] );
443          OUT_RING( (HC_SubA_HTXnTBLRCc << 24) | vmesa->regHTXnTBLRCc[1] );
444          OUT_RING( (HC_SubA_HTXnTBLRCbias << 24) | vmesa->regHTXnTBLRCbias[1] );
445          OUT_RING( (HC_SubA_HTXnTBC << 24) | vmesa->regHTXnTBC[1] );
446          OUT_RING( (HC_SubA_HTXnTRAH << 24) | vmesa->regHTXnTRAH[1] );
447 /*       OUT_RING( (HC_SubA_HTXnCLODu << 24) | vmesa->regHTXnCLOD[1] ); */
448          ADVANCE_RING();
449
450          /* KW:  This test never succeeds:
451           */
452          if (t->regTexFM == HC_HTXnFM_Index8) {
453             const struct gl_color_table *table = &texObj->Palette;
454             const GLfloat *tableF = table->TableF;
455
456             BEGIN_RING(2 + table->Size);
457             OUT_RING( HC_HEADER2 );
458             OUT_RING( (HC_ParaType_Palette << 16) | (texunit << 24) );
459             for (j = 0; j < table->Size; j++) {
460                OUT_RING( tableF[j] );
461             }
462             ADVANCE_RING();
463          }
464
465          QWORD_PAD_RING();
466       }
467    }
468     
469 #if 0
470    /* Polygon stipple is broken - for certain stipple values,
471     * eg. 0xf0f0f0f0, the hardware will refuse to accept the stipple.
472     * Coincidentally, conform generates just such a stipple.
473     */
474    if (ctx->Polygon.StippleFlag) {
475       GLuint *stipple = &ctx->PolygonStipple[0];
476       __DRIdrawable *dPriv = vmesa->driDrawable;
477       struct via_renderbuffer *const vrb = 
478         (struct via_renderbuffer *) dPriv->driverPrivate;
479       GLint i;
480         
481       BEGIN_RING(38);
482       OUT_RING( HC_HEADER2 );             
483
484       OUT_RING( ((HC_ParaType_Palette << 16) | (HC_SubType_Stipple << 24)) );
485       for (i = 31; i >= 0; i--) {
486          GLint j;
487          GLuint k = 0;
488
489          /* Need to flip bits left to right:
490           */
491          for (j = 0 ; j < 32; j++)
492             if (stipple[i] & (1<<j))
493                k |= 1 << (31-j);
494
495          OUT_RING( k );     
496       }
497
498       OUT_RING( HC_HEADER2 );                     
499       OUT_RING( (HC_ParaType_NotTex << 16) );
500       OUT_RING( (HC_SubA_HSPXYOS << 24) );
501       OUT_RING( (HC_SubA_HSPXYOS << 24) );
502
503       ADVANCE_RING();
504    }
505 #endif
506    
507    vmesa->newEmitState = 0;
508 }
509
510
511 static INLINE GLuint viaPackColor(GLuint bpp,
512                                   GLubyte r, GLubyte g,
513                                   GLubyte b, GLubyte a)
514 {
515     switch (bpp) {
516     case 16:
517         return PACK_COLOR_565(r, g, b);
518     case 32:
519         return PACK_COLOR_8888(a, r, g, b);        
520     default:
521        assert(0);
522        return 0;
523    }
524 }
525
526 static void viaBlendEquationSeparate(struct gl_context *ctx,
527                                      GLenum rgbMode, 
528                                      GLenum aMode)
529 {
530     if (VIA_DEBUG & DEBUG_STATE) 
531        fprintf(stderr, "%s in\n", __FUNCTION__);
532
533     /* GL_EXT_blend_equation_separate not supported */
534     ASSERT(rgbMode == aMode);
535
536     /* Can only do GL_ADD equation in hardware */
537     FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_BLEND_EQ, 
538              rgbMode != GL_FUNC_ADD_EXT);
539
540     /* BlendEquation sets ColorLogicOpEnabled in an unexpected
541      * manner.
542      */
543     FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_LOGICOP,
544              (ctx->Color.ColorLogicOpEnabled &&
545               ctx->Color.LogicOp != GL_COPY));
546 }
547
548 static void viaBlendFunc(struct gl_context *ctx, GLenum sfactor, GLenum dfactor)
549 {
550     struct via_context *vmesa = VIA_CONTEXT(ctx);
551     GLboolean fallback = GL_FALSE;
552     if (VIA_DEBUG & DEBUG_STATE) 
553        fprintf(stderr, "%s in\n", __FUNCTION__);
554
555     switch (ctx->Color.Blend[0].SrcRGB) {
556     case GL_SRC_ALPHA_SATURATE:  
557     case GL_CONSTANT_COLOR:
558     case GL_ONE_MINUS_CONSTANT_COLOR:
559     case GL_CONSTANT_ALPHA:
560     case GL_ONE_MINUS_CONSTANT_ALPHA:
561         fallback = GL_TRUE;
562         break;
563     default:
564         break;
565     }
566
567     switch (ctx->Color.Blend[0].DstRGB) {
568     case GL_CONSTANT_COLOR:
569     case GL_ONE_MINUS_CONSTANT_COLOR:
570     case GL_CONSTANT_ALPHA:
571     case GL_ONE_MINUS_CONSTANT_ALPHA:
572         fallback = GL_TRUE;
573         break;
574     default:
575         break;
576     }
577
578     FALLBACK(vmesa, VIA_FALLBACK_BLEND_FUNC, fallback);
579 }
580
581 /* Shouldn't be called as the extension is disabled.
582  */
583 static void viaBlendFuncSeparate(struct gl_context *ctx, GLenum sfactorRGB,
584                                  GLenum dfactorRGB, GLenum sfactorA,
585                                  GLenum dfactorA)
586 {
587     if (dfactorRGB != dfactorA || sfactorRGB != sfactorA) {
588         _mesa_error(ctx, GL_INVALID_OPERATION, "glBlendEquation (disabled)");
589     }
590
591     viaBlendFunc(ctx, sfactorRGB, dfactorRGB);
592 }
593
594
595
596
597 /* =============================================================
598  * Hardware clipping
599  */
600 static void viaScissor(struct gl_context *ctx, GLint x, GLint y,
601                        GLsizei w, GLsizei h)
602 {
603     struct via_context *vmesa = VIA_CONTEXT(ctx);
604
605     if (!vmesa->driDrawable)
606        return;
607
608     if (VIA_DEBUG & DEBUG_STATE)
609        fprintf(stderr, "%s %d,%d %dx%d, drawH %d\n", __FUNCTION__, 
610                x,y,w,h, vmesa->driDrawable->h);
611
612     if (vmesa->scissor) {
613         VIA_FLUSH_DMA(vmesa); /* don't pipeline cliprect changes */
614     }
615
616     vmesa->scissorRect.x1 = x;
617     vmesa->scissorRect.y1 = vmesa->driDrawable->h - y - h;
618     vmesa->scissorRect.x2 = x + w;
619     vmesa->scissorRect.y2 = vmesa->driDrawable->h - y;
620 }
621
622 static void viaEnable(struct gl_context *ctx, GLenum cap, GLboolean state)
623 {
624    struct via_context *vmesa = VIA_CONTEXT(ctx);
625
626    switch (cap) {
627    case GL_SCISSOR_TEST:
628       VIA_FLUSH_DMA(vmesa);
629       vmesa->scissor = state;
630       break;
631    default:
632       break;
633    }
634 }
635
636
637
638 /* Fallback to swrast for select and feedback.
639  */
640 static void viaRenderMode(struct gl_context *ctx, GLenum mode)
641 {
642     FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_RENDERMODE, (mode != GL_RENDER));
643 }
644
645
646 static void viaDrawBuffer(struct gl_context *ctx, GLenum mode)
647 {
648    struct via_context *vmesa = VIA_CONTEXT(ctx);
649
650    if (VIA_DEBUG & (DEBUG_DRI|DEBUG_STATE)) 
651       fprintf(stderr, "%s in\n", __FUNCTION__);
652
653    if (!ctx->DrawBuffer)
654       return;
655
656    if (ctx->DrawBuffer->_NumColorDrawBuffers != 1) {
657       FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_TRUE);
658       return;
659    }
660
661    switch ( ctx->DrawBuffer->_ColorDrawBufferIndexes[0] ) {
662    case BUFFER_FRONT_LEFT:
663       VIA_FLUSH_DMA(vmesa);
664       vmesa->drawBuffer = &vmesa->front;
665       FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
666       break;
667    case BUFFER_BACK_LEFT:
668       VIA_FLUSH_DMA(vmesa);
669       vmesa->drawBuffer = &vmesa->back;
670       FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_FALSE);
671       break;
672    default:
673       FALLBACK(vmesa, VIA_FALLBACK_DRAW_BUFFER, GL_TRUE);
674       return;
675    }
676
677
678    viaXMesaWindowMoved(vmesa);
679 }
680
681 static void viaClearColor(struct gl_context *ctx, const GLfloat color[4])
682 {
683     struct via_context *vmesa = VIA_CONTEXT(ctx);
684     GLubyte pcolor[4];
685     CLAMPED_FLOAT_TO_UBYTE(pcolor[0], color[0]);
686     CLAMPED_FLOAT_TO_UBYTE(pcolor[1], color[1]);
687     CLAMPED_FLOAT_TO_UBYTE(pcolor[2], color[2]);
688     CLAMPED_FLOAT_TO_UBYTE(pcolor[3], color[3]);
689     vmesa->ClearColor = viaPackColor(vmesa->viaScreen->bitsPerPixel,
690                                      pcolor[0], pcolor[1],
691                                      pcolor[2], pcolor[3]);
692 }
693
694 #define WRITEMASK_ALPHA_SHIFT 31
695 #define WRITEMASK_RED_SHIFT   30
696 #define WRITEMASK_GREEN_SHIFT 29
697 #define WRITEMASK_BLUE_SHIFT  28
698
699 static void viaColorMask(struct gl_context *ctx,
700                          GLboolean r, GLboolean g,
701                          GLboolean b, GLboolean a)
702 {
703    struct via_context *vmesa = VIA_CONTEXT( ctx );
704
705    if (VIA_DEBUG & DEBUG_STATE)
706       fprintf(stderr, "%s r(%d) g(%d) b(%d) a(%d)\n", __FUNCTION__, r, g, b, a);
707
708    vmesa->ClearMask = (((!r) << WRITEMASK_RED_SHIFT) |
709                        ((!g) << WRITEMASK_GREEN_SHIFT) |
710                        ((!b) << WRITEMASK_BLUE_SHIFT) |
711                        ((!a) << WRITEMASK_ALPHA_SHIFT));
712 }
713
714
715
716 /* This hardware just isn't capable of private back buffers without
717  * glitches and/or a hefty locking scheme.
718  */
719 void viaCalcViewport(struct gl_context *ctx)
720 {
721     struct via_context *vmesa = VIA_CONTEXT(ctx);
722     __DRIdrawable *dPriv = vmesa->driDrawable;
723     struct via_renderbuffer *const vrb = 
724       (struct via_renderbuffer *) dPriv->driverPrivate;
725     const GLfloat *v = ctx->Viewport._WindowMap.m;
726     GLfloat *m = vmesa->ViewportMatrix.m;
727     
728     m[MAT_SX] =   v[MAT_SX];
729     m[MAT_TX] =   v[MAT_TX] + vrb->drawX + SUBPIXEL_X;
730     m[MAT_SY] = - v[MAT_SY];
731     m[MAT_TY] = - v[MAT_TY] + vrb->drawY + SUBPIXEL_Y + vrb->drawH;
732     m[MAT_SZ] =   v[MAT_SZ] * (1.0 / vmesa->depth_max);
733     m[MAT_TZ] =   v[MAT_TZ] * (1.0 / vmesa->depth_max);
734 }
735
736 static void viaViewport(struct gl_context *ctx,
737                         GLint x, GLint y,
738                         GLsizei width, GLsizei height)
739 {
740     viaCalcViewport(ctx);
741 }
742
743 static void viaDepthRange(struct gl_context *ctx,
744                           GLclampd nearval, GLclampd farval)
745 {
746     viaCalcViewport(ctx);
747 }
748
749 void viaInitState(struct gl_context *ctx)
750 {
751     struct via_context *vmesa = VIA_CONTEXT(ctx);
752
753     vmesa->regCmdB = HC_ACMD_HCmdB;
754     vmesa->regEnable = HC_HenCW_MASK;
755
756    /* Mesa should do this for us:
757     */
758
759    ctx->Driver.BlendEquationSeparate( ctx, 
760                                       ctx->Color.Blend[0].EquationRGB,
761                                       ctx->Color.Blend[0].EquationA);
762
763    ctx->Driver.BlendFuncSeparate( ctx,
764                                   ctx->Color.Blend[0].SrcRGB,
765                                   ctx->Color.Blend[0].DstRGB,
766                                   ctx->Color.Blend[0].SrcA,
767                                   ctx->Color.Blend[0].DstA);
768
769    ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y,
770                         ctx->Scissor.Width, ctx->Scissor.Height );
771
772    ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] );
773 }
774
775 /**
776  * Convert S and T texture coordinate wrap modes to hardware bits.
777  */
778 static uint32_t
779 get_wrap_mode( GLenum sWrap, GLenum tWrap )
780 {
781     uint32_t v = 0;
782
783
784     switch( sWrap ) {
785     case GL_REPEAT:
786         v |= HC_HTXnMPMD_Srepeat;
787         break;
788     case GL_CLAMP:
789     case GL_CLAMP_TO_EDGE:
790         v |= HC_HTXnMPMD_Sclamp;
791         break;
792     case GL_MIRRORED_REPEAT:
793         v |= HC_HTXnMPMD_Smirror;
794         break;
795     }
796
797     switch( tWrap ) {
798     case GL_REPEAT:
799         v |= HC_HTXnMPMD_Trepeat;
800         break;
801     case GL_CLAMP:
802     case GL_CLAMP_TO_EDGE:
803         v |= HC_HTXnMPMD_Tclamp;
804         break;
805     case GL_MIRRORED_REPEAT:
806         v |= HC_HTXnMPMD_Tmirror;
807         break;
808     }
809     
810     return v;
811 }
812
813 static uint32_t
814 get_minmag_filter( GLenum min, GLenum mag )
815 {
816     uint32_t v = 0;
817
818     switch (min) {
819     case GL_NEAREST:
820         v = HC_HTXnFLSs_Nearest |
821             HC_HTXnFLTs_Nearest;
822         break;
823     case GL_LINEAR:
824         v = HC_HTXnFLSs_Linear |
825             HC_HTXnFLTs_Linear;
826         break;
827     case GL_NEAREST_MIPMAP_NEAREST:
828         v = HC_HTXnFLSs_Nearest |
829             HC_HTXnFLTs_Nearest;
830         v |= HC_HTXnFLDs_Nearest;
831         break;
832     case GL_LINEAR_MIPMAP_NEAREST:
833         v = HC_HTXnFLSs_Linear |
834             HC_HTXnFLTs_Linear;
835         v |= HC_HTXnFLDs_Nearest;
836         break;
837     case GL_NEAREST_MIPMAP_LINEAR:
838         v = HC_HTXnFLSs_Nearest |
839             HC_HTXnFLTs_Nearest;
840         v |= HC_HTXnFLDs_Linear;
841         break;
842     case GL_LINEAR_MIPMAP_LINEAR:
843         v = HC_HTXnFLSs_Linear |
844             HC_HTXnFLTs_Linear;
845         v |= HC_HTXnFLDs_Linear;
846         break;
847     default:
848         break;
849     }
850
851     switch (mag) {
852     case GL_LINEAR:
853         v |= HC_HTXnFLSe_Linear |
854              HC_HTXnFLTe_Linear;
855         break;
856     case GL_NEAREST:
857         v |= HC_HTXnFLSe_Nearest |
858              HC_HTXnFLTe_Nearest;
859         break;
860     default:
861         break;
862     }
863
864     return v;
865 }
866
867
868 static GLboolean viaChooseTextureState(struct gl_context *ctx) 
869 {
870     struct via_context *vmesa = VIA_CONTEXT(ctx);
871     struct gl_texture_unit *texUnit0 = &ctx->Texture.Unit[0];
872     struct gl_texture_unit *texUnit1 = &ctx->Texture.Unit[1];
873
874     if (texUnit0->_ReallyEnabled || texUnit1->_ReallyEnabled) {
875         vmesa->regEnable |= HC_HenTXMP_MASK | HC_HenTXCH_MASK | HC_HenTXPP_MASK;
876
877         if (texUnit0->_ReallyEnabled) {
878             struct gl_texture_object *texObj = texUnit0->_Current;
879    
880             vmesa->regHTXnTB[0] = get_minmag_filter( texObj->Sampler.MinFilter,
881                                                     texObj->Sampler.MagFilter );
882
883             vmesa->regHTXnMPMD[0] &= ~(HC_HTXnMPMD_SMASK | HC_HTXnMPMD_TMASK);
884             vmesa->regHTXnMPMD[0] |= get_wrap_mode( texObj->Sampler.WrapS,
885                                                    texObj->Sampler.WrapT );
886
887             vmesa->regHTXnTB[0] &= ~(HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
888             if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
889                vmesa->regHTXnTB[0] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
890                vmesa->regHTXnTBC[0] = 
891                   PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[0]),
892                                  FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[1]),
893                                  FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[2]));
894                vmesa->regHTXnTRAH[0] = FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[3]);
895             }
896
897             if (texUnit0->LodBias != 0.0f) {
898                GLuint b = viaComputeLodBias(texUnit0->LodBias);
899                vmesa->regHTXnTB[0] &= ~HC_HTXnFLDs_MASK;
900                vmesa->regHTXnTB[0] |= HC_HTXnFLDs_ConstLOD;
901                vmesa->regHTXnCLOD[0] = (b&0x1f) | (((~b)&0x1f)<<10); /* FIXME */
902             }
903
904             if (!viaTexCombineState( vmesa, texUnit0->_CurrentCombine, 0 )) {
905                if (VIA_DEBUG & DEBUG_TEXTURE)
906                   fprintf(stderr, "viaTexCombineState failed for unit 0\n");
907                return GL_FALSE;
908             }
909         }
910
911         if (texUnit1->_ReallyEnabled) {
912             struct gl_texture_object *texObj = texUnit1->_Current;
913
914             vmesa->regHTXnTB[1] = get_minmag_filter( texObj->Sampler.MinFilter,
915                                                     texObj->Sampler.MagFilter );
916             vmesa->regHTXnMPMD[1] &= ~(HC_HTXnMPMD_SMASK | HC_HTXnMPMD_TMASK);
917             vmesa->regHTXnMPMD[1] |= get_wrap_mode( texObj->Sampler.WrapS,
918                                                    texObj->Sampler.WrapT );
919
920             vmesa->regHTXnTB[1] &= ~(HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
921             if (texObj->Image[0][texObj->BaseLevel]->Border > 0) {
922                vmesa->regHTXnTB[1] |= (HC_HTXnTB_TBC_S | HC_HTXnTB_TBC_T);
923                vmesa->regHTXnTBC[1] = 
924                   PACK_COLOR_888(FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[0]),
925                                  FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[1]),
926                                  FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[2]));
927                vmesa->regHTXnTRAH[1] = FLOAT_TO_UBYTE(texObj->Sampler.BorderColor.f[3]);
928             }
929
930
931             if (texUnit1->LodBias != 0.0f) {
932                GLuint b = viaComputeLodBias(texUnit1->LodBias);
933                vmesa->regHTXnTB[1] &= ~HC_HTXnFLDs_MASK;
934                vmesa->regHTXnTB[1] |= HC_HTXnFLDs_ConstLOD;
935                vmesa->regHTXnCLOD[1] = (b&0x1f) | (((~b)&0x1f)<<10); /* FIXME */
936             }
937
938             if (!viaTexCombineState( vmesa, texUnit1->_CurrentCombine, 1 )) {
939                if (VIA_DEBUG & DEBUG_TEXTURE)
940                   fprintf(stderr, "viaTexCombineState failed for unit 1\n");
941                return GL_FALSE;
942             }
943         }
944     }
945     else {
946         vmesa->regEnable &= ~(HC_HenTXMP_MASK | HC_HenTXCH_MASK | 
947                               HC_HenTXPP_MASK);
948     }
949     
950     return GL_TRUE;
951 }
952
953 static void viaChooseColorState(struct gl_context *ctx) 
954 {
955     struct via_context *vmesa = VIA_CONTEXT(ctx);
956     GLenum s = ctx->Color.Blend[0].SrcRGB;
957     GLenum d = ctx->Color.Blend[0].DstRGB;
958
959     /* The HW's blending equation is:
960      * (Ca * FCa + Cbias + Cb * FCb) << Cshift
961      */
962
963     if (ctx->Color.BlendEnabled) {
964         vmesa->regEnable |= HC_HenABL_MASK;
965         /* Ca  -- always from source color.
966          */
967         vmesa->regHABLCsat = HC_HABLCsat_MASK | HC_HABLCa_OPC | HC_HABLCa_Csrc;
968         /* Aa  -- always from source alpha.
969          */
970         vmesa->regHABLAsat = HC_HABLAsat_MASK | HC_HABLAa_OPA | HC_HABLAa_Asrc;
971         /* FCa -- depend on following condition.
972          * FAa -- depend on following condition.
973          */
974         switch (s) {
975         case GL_ZERO:
976             /* (0, 0, 0, 0)
977              */
978             vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
979             vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA;
980             vmesa->regHABLRFCa = 0x0;
981             vmesa->regHABLRAa = 0x0;
982             break;
983         case GL_ONE:
984             /* (1, 1, 1, 1)
985              */
986             vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_HABLRCa;
987             vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_HABLFRA;
988             vmesa->regHABLRFCa = 0x0;
989             vmesa->regHABLRAa = 0x0;
990             break;
991         case GL_SRC_COLOR:
992             /* (Rs, Gs, Bs, As)
993              */
994             vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Csrc;
995             vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc;
996             break;
997         case GL_ONE_MINUS_SRC_COLOR:
998             /* (1, 1, 1, 1) - (Rs, Gs, Bs, As)
999              */
1000             vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Csrc;
1001             vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc;
1002             break;
1003         case GL_DST_COLOR:
1004             /* (Rd, Gd, Bd, Ad)
1005              */
1006             vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Cdst;
1007             vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst;
1008             break;
1009         case GL_ONE_MINUS_DST_COLOR:
1010             /* (1, 1, 1, 1) - (Rd, Gd, Bd, Ad)
1011              */
1012             vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Cdst;
1013             vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst;
1014             break;
1015         case GL_SRC_ALPHA:
1016             /* (As, As, As, As)
1017              */
1018             vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Asrc;
1019             vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Asrc;
1020             break;
1021         case GL_ONE_MINUS_SRC_ALPHA:
1022             /* (1, 1, 1, 1) - (As, As, As, As)
1023              */
1024             vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Asrc;
1025             vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Asrc;
1026             break;
1027         case GL_DST_ALPHA:
1028             {
1029                 if (vmesa->viaScreen->bitsPerPixel == 16) {
1030                     /* (1, 1, 1, 1)
1031                      */
1032                     vmesa->regHABLCsat |= (HC_HABLFCa_InvOPC | 
1033                                            HC_HABLFCa_HABLRCa);
1034                     vmesa->regHABLAsat |= (HC_HABLFAa_InvOPA | 
1035                                            HC_HABLFAa_HABLFRA);
1036                     vmesa->regHABLRFCa = 0x0;
1037                     vmesa->regHABLRAa = 0x0;
1038                 }
1039                 else {
1040                     /* (Ad, Ad, Ad, Ad)
1041                      */
1042                     vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_Adst;
1043                     vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_Adst;
1044                 }
1045             }
1046             break;
1047         case GL_ONE_MINUS_DST_ALPHA:
1048             {
1049                 if (vmesa->viaScreen->bitsPerPixel == 16) {
1050                     /* (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0)
1051                      */
1052                     vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
1053                     vmesa->regHABLAsat |= HC_HABLFAa_OPA | HC_HABLFAa_HABLFRA;
1054                     vmesa->regHABLRFCa = 0x0;
1055                     vmesa->regHABLRAa = 0x0;
1056                 }
1057                 else {
1058                     /* (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)
1059                      */
1060                     vmesa->regHABLCsat |= HC_HABLFCa_InvOPC | HC_HABLFCa_Adst;
1061                     vmesa->regHABLAsat |= HC_HABLFAa_InvOPA | HC_HABLFAa_Adst;
1062                 }
1063             }
1064             break;
1065         case GL_SRC_ALPHA_SATURATE:
1066             {
1067                 if (vmesa->viaScreen->bitsPerPixel == 16) {
1068                     /* (f, f, f, 1), f = min(As, 1 - Ad) = min(As, 1 - 1) = 0
1069                      * So (f, f, f, 1) = (0, 0, 0, 1)
1070                      */
1071                     vmesa->regHABLCsat |= HC_HABLFCa_OPC | HC_HABLFCa_HABLRCa;
1072                     vmesa->regHABLAsat |= (HC_HABLFAa_InvOPA | 
1073                                            HC_HABLFAa_HABLFRA);
1074                     vmesa->regHABLRFCa = 0x0;
1075                     vmesa->regHABLRAa = 0x0;
1076                 }
1077                 else {
1078                     /* (f, f, f, 1), f = min(As, 1 - Ad)
1079                      */
1080                     vmesa->regHABLCsat |= (HC_HABLFCa_OPC | 
1081                                            HC_HABLFCa_mimAsrcInvAdst);
1082                     vmesa->regHABLAsat |= (HC_HABLFAa_InvOPA | 
1083                                            HC_HABLFAa_HABLFRA);
1084                     vmesa->regHABLRFCa = 0x0;
1085                     vmesa->regHABLRAa = 0x0;
1086                 }
1087             }
1088             break;
1089         }
1090
1091         /* Op is add.
1092          */
1093
1094         /* bias is 0.
1095          */
1096         vmesa->regHABLCsat |= HC_HABLCbias_HABLRCbias;
1097         vmesa->regHABLAsat |= HC_HABLAbias_HABLRAbias;
1098
1099         /* Cb  -- always from destination color.
1100          */
1101         vmesa->regHABLCop = HC_HABLCb_OPC | HC_HABLCb_Cdst;
1102         /* Ab  -- always from destination alpha.
1103          */
1104         vmesa->regHABLAop = HC_HABLAb_OPA | HC_HABLAb_Adst;
1105         /* FCb -- depend on following condition.
1106          */
1107         switch (d) {
1108         case GL_ZERO:
1109             /* (0, 0, 0, 0)
1110              */
1111             vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
1112             vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
1113             vmesa->regHABLRFCb = 0x0;
1114             vmesa->regHABLRAb = 0x0;
1115             break;
1116         case GL_ONE:
1117             /* (1, 1, 1, 1)
1118              */
1119             vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb;
1120             vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA;
1121             vmesa->regHABLRFCb = 0x0;
1122             vmesa->regHABLRAb = 0x0;
1123             break;
1124         case GL_SRC_COLOR:
1125             /* (Rs, Gs, Bs, As)
1126              */
1127             vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Csrc;
1128             vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc;
1129             break;
1130         case GL_ONE_MINUS_SRC_COLOR:
1131             /* (1, 1, 1, 1) - (Rs, Gs, Bs, As)
1132              */
1133             vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Csrc;
1134             vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Asrc;
1135             break;
1136         case GL_DST_COLOR:
1137             /* (Rd, Gd, Bd, Ad)
1138              */
1139             vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Cdst;
1140             vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst;
1141             break;
1142         case GL_ONE_MINUS_DST_COLOR:
1143             /* (1, 1, 1, 1) - (Rd, Gd, Bd, Ad)
1144              */
1145             vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Cdst;
1146             vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst;
1147             break;
1148         case GL_SRC_ALPHA:
1149             /* (As, As, As, As)
1150              */
1151             vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Asrc;
1152             vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Asrc;
1153             break;
1154         case GL_ONE_MINUS_SRC_ALPHA:
1155             /* (1, 1, 1, 1) - (As, As, As, As)
1156              */
1157             vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Asrc;
1158             vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Asrc;
1159             break;
1160         case GL_DST_ALPHA:
1161             {
1162                 if (vmesa->viaScreen->bitsPerPixel == 16) {
1163                     /* (1, 1, 1, 1)
1164                      */
1165                     vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_HABLRCb;
1166                     vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_HABLFRA;
1167                     vmesa->regHABLRFCb = 0x0;
1168                     vmesa->regHABLRAb = 0x0;
1169                 }
1170                 else {
1171                     /* (Ad, Ad, Ad, Ad)
1172                      */
1173                     vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_Adst;
1174                     vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_Adst;
1175                 }
1176             }
1177             break;
1178         case GL_ONE_MINUS_DST_ALPHA:
1179             {
1180                 if (vmesa->viaScreen->bitsPerPixel == 16) {
1181                     /* (1, 1, 1, 1) - (1, 1, 1, 1) = (0, 0, 0, 0)
1182                      */
1183                     vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
1184                     vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
1185                     vmesa->regHABLRFCb = 0x0;
1186                     vmesa->regHABLRAb = 0x0;
1187                 }
1188                 else {
1189                     /* (1, 1, 1, 1) - (Ad, Ad, Ad, Ad)
1190                      */
1191                     vmesa->regHABLCop |= HC_HABLFCb_InvOPC | HC_HABLFCb_Adst;
1192                     vmesa->regHABLAop |= HC_HABLFAb_InvOPA | HC_HABLFAb_Adst;
1193                 }
1194             }
1195             break;
1196         default:
1197             vmesa->regHABLCop |= HC_HABLFCb_OPC | HC_HABLFCb_HABLRCb;
1198             vmesa->regHABLAop |= HC_HABLFAb_OPA | HC_HABLFAb_HABLFRA;
1199             vmesa->regHABLRFCb = 0x0;
1200             vmesa->regHABLRAb = 0x0;
1201             break;
1202         }
1203
1204         if (vmesa->viaScreen->bitsPerPixel <= 16)
1205             vmesa->regEnable &= ~HC_HenDT_MASK;
1206
1207     }
1208     else {
1209         vmesa->regEnable &= (~HC_HenABL_MASK);
1210     }
1211
1212     if (ctx->Color.AlphaEnabled) {
1213         vmesa->regEnable |= HC_HenAT_MASK;
1214         vmesa->regHATMD = FLOAT_TO_UBYTE(ctx->Color.AlphaRef) |
1215             ((ctx->Color.AlphaFunc - GL_NEVER) << 8);
1216     }
1217     else {
1218         vmesa->regEnable &= (~HC_HenAT_MASK);
1219     }
1220
1221     if (ctx->Color.DitherFlag && (vmesa->viaScreen->bitsPerPixel < 32)) {
1222         if (ctx->Color.BlendEnabled) {
1223             vmesa->regEnable &= ~HC_HenDT_MASK;
1224         }
1225         else {
1226             vmesa->regEnable |= HC_HenDT_MASK;
1227         }
1228     }
1229
1230
1231     vmesa->regEnable &= ~HC_HenDT_MASK;
1232
1233     if (ctx->Color.ColorLogicOpEnabled) 
1234         vmesa->regHROP = ROP[ctx->Color.LogicOp & 0xF];
1235     else
1236         vmesa->regHROP = HC_HROP_P;
1237
1238     vmesa->regHFBBMSKL = PACK_COLOR_888(ctx->Color.ColorMask[0][0],
1239                                         ctx->Color.ColorMask[0][1],
1240                                         ctx->Color.ColorMask[0][2]);
1241     vmesa->regHROP |= ctx->Color.ColorMask[0][3];
1242
1243     if (ctx->Color.ColorMask[0][3])
1244         vmesa->regEnable |= HC_HenAW_MASK;
1245     else
1246         vmesa->regEnable &= ~HC_HenAW_MASK;
1247 }
1248
1249 static void viaChooseFogState(struct gl_context *ctx) 
1250 {
1251     struct via_context *vmesa = VIA_CONTEXT(ctx);
1252
1253     if (ctx->Fog.Enabled) {
1254         GLubyte r, g, b, a;
1255
1256         vmesa->regEnable |= HC_HenFOG_MASK;
1257
1258         /* Use fog equation 0 (OpenGL's default) & local fog.
1259          */
1260         vmesa->regHFogLF = 0x0;
1261
1262         r = (GLubyte)(ctx->Fog.Color[0] * 255.0F);
1263         g = (GLubyte)(ctx->Fog.Color[1] * 255.0F);
1264         b = (GLubyte)(ctx->Fog.Color[2] * 255.0F);
1265         a = (GLubyte)(ctx->Fog.Color[3] * 255.0F);
1266         vmesa->regHFogCL = (r << 16) | (g << 8) | b;
1267         vmesa->regHFogCH = a;
1268     }
1269     else {
1270         vmesa->regEnable &= ~HC_HenFOG_MASK;
1271     }
1272 }
1273
1274 static void viaChooseDepthState(struct gl_context *ctx) 
1275 {
1276     struct via_context *vmesa = VIA_CONTEXT(ctx);
1277     if (ctx->Depth.Test) {
1278         vmesa->regEnable |= HC_HenZT_MASK;
1279         if (ctx->Depth.Mask)
1280             vmesa->regEnable |= HC_HenZW_MASK;
1281         else
1282             vmesa->regEnable &= (~HC_HenZW_MASK);
1283         vmesa->regHZWTMD = (ctx->Depth.Func - GL_NEVER) << 16;
1284         
1285     }
1286     else {
1287         vmesa->regEnable &= ~HC_HenZT_MASK;
1288         
1289         /*=* [DBG] racer : can't display cars in car selection menu *=*/
1290         /*if (ctx->Depth.Mask)
1291             vmesa->regEnable |= HC_HenZW_MASK;
1292         else
1293             vmesa->regEnable &= (~HC_HenZW_MASK);*/
1294         vmesa->regEnable &= (~HC_HenZW_MASK);
1295     }
1296 }
1297
1298 static void viaChooseLineState(struct gl_context *ctx) 
1299 {
1300     struct via_context *vmesa = VIA_CONTEXT(ctx);
1301
1302     if (ctx->Line.StippleFlag) {
1303         vmesa->regEnable |= HC_HenLP_MASK;
1304         vmesa->regHLP = ctx->Line.StipplePattern;
1305         vmesa->regHLPRF = ctx->Line.StippleFactor;
1306     }
1307     else {
1308         vmesa->regEnable &= ~HC_HenLP_MASK;
1309     }
1310 }
1311
1312 static void viaChoosePolygonState(struct gl_context *ctx) 
1313 {
1314     struct via_context *vmesa = VIA_CONTEXT(ctx);
1315
1316 #if 0
1317     /* Polygon stipple is broken - see via_state.c
1318      */
1319     if (ctx->Polygon.StippleFlag) {
1320         vmesa->regEnable |= HC_HenSP_MASK;
1321     }
1322     else {
1323         vmesa->regEnable &= ~HC_HenSP_MASK;
1324     }
1325 #else
1326     FALLBACK(vmesa, VIA_FALLBACK_POLY_STIPPLE, 
1327              ctx->Polygon.StippleFlag);
1328 #endif
1329
1330     if (ctx->Polygon.CullFlag) {
1331         vmesa->regEnable |= HC_HenFBCull_MASK;
1332     }
1333     else {
1334         vmesa->regEnable &= ~HC_HenFBCull_MASK;
1335     }
1336 }
1337
1338 static void viaChooseStencilState(struct gl_context *ctx) 
1339 {
1340     struct via_context *vmesa = VIA_CONTEXT(ctx);
1341     
1342     if (ctx->Stencil._Enabled) {
1343         GLuint temp;
1344
1345         vmesa->regEnable |= HC_HenST_MASK;
1346         temp = (ctx->Stencil.Ref[0] & 0xFF) << HC_HSTREF_SHIFT;
1347         temp |= 0xFF << HC_HSTOPMSK_SHIFT;
1348         temp |= (ctx->Stencil.ValueMask[0] & 0xFF);
1349         vmesa->regHSTREF = temp;
1350
1351         temp = (ctx->Stencil.Function[0] - GL_NEVER) << 16;
1352
1353         switch (ctx->Stencil.FailFunc[0]) {
1354         case GL_KEEP:
1355             temp |= HC_HSTOPSF_KEEP;
1356             break;
1357         case GL_ZERO:
1358             temp |= HC_HSTOPSF_ZERO;
1359             break;
1360         case GL_REPLACE:
1361             temp |= HC_HSTOPSF_REPLACE;
1362             break;
1363         case GL_INVERT:
1364             temp |= HC_HSTOPSF_INVERT;
1365             break;
1366         case GL_INCR:
1367             temp |= HC_HSTOPSF_INCR;
1368             break;
1369         case GL_DECR:
1370             temp |= HC_HSTOPSF_DECR;
1371             break;
1372         }
1373
1374         switch (ctx->Stencil.ZFailFunc[0]) {
1375         case GL_KEEP:
1376             temp |= HC_HSTOPSPZF_KEEP;
1377             break;
1378         case GL_ZERO:
1379             temp |= HC_HSTOPSPZF_ZERO;
1380             break;
1381         case GL_REPLACE:
1382             temp |= HC_HSTOPSPZF_REPLACE;
1383             break;
1384         case GL_INVERT:
1385             temp |= HC_HSTOPSPZF_INVERT;
1386             break;
1387         case GL_INCR:
1388             temp |= HC_HSTOPSPZF_INCR;
1389             break;
1390         case GL_DECR:
1391             temp |= HC_HSTOPSPZF_DECR;
1392             break;
1393         }
1394
1395         switch (ctx->Stencil.ZPassFunc[0]) {
1396         case GL_KEEP:
1397             temp |= HC_HSTOPSPZP_KEEP;
1398             break;
1399         case GL_ZERO:
1400             temp |= HC_HSTOPSPZP_ZERO;
1401             break;
1402         case GL_REPLACE:
1403             temp |= HC_HSTOPSPZP_REPLACE;
1404             break;
1405         case GL_INVERT:
1406             temp |= HC_HSTOPSPZP_INVERT;
1407             break;
1408         case GL_INCR:
1409             temp |= HC_HSTOPSPZP_INCR;
1410             break;
1411         case GL_DECR:
1412             temp |= HC_HSTOPSPZP_DECR;
1413             break;
1414         }
1415         vmesa->regHSTMD = temp;
1416     }
1417     else {
1418         vmesa->regEnable &= ~HC_HenST_MASK;
1419     }
1420 }
1421
1422
1423
1424 static void viaChooseTriangle(struct gl_context *ctx) 
1425 {       
1426     struct via_context *vmesa = VIA_CONTEXT(ctx);
1427
1428     if (ctx->Polygon.CullFlag == GL_TRUE) {
1429         switch (ctx->Polygon.CullFaceMode) {
1430         case GL_FRONT:
1431             if (ctx->Polygon.FrontFace == GL_CCW)
1432                 vmesa->regCmdB |= HC_HBFace_MASK;
1433             else
1434                 vmesa->regCmdB &= ~HC_HBFace_MASK;
1435             break;
1436         case GL_BACK:
1437             if (ctx->Polygon.FrontFace == GL_CW)
1438                 vmesa->regCmdB |= HC_HBFace_MASK;
1439             else
1440                 vmesa->regCmdB &= ~HC_HBFace_MASK;
1441             break;
1442         case GL_FRONT_AND_BACK:
1443             return;
1444         }
1445     }
1446 }
1447
1448 void viaValidateState( struct gl_context *ctx )
1449 {
1450     struct via_context *vmesa = VIA_CONTEXT(ctx);
1451
1452     if (vmesa->newState & _NEW_TEXTURE) {
1453        GLboolean ok = (viaChooseTextureState(ctx) &&
1454                        viaUpdateTextureState(ctx));
1455
1456        FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, !ok);
1457     }
1458
1459     if (vmesa->newState & _NEW_COLOR)
1460         viaChooseColorState(ctx);
1461
1462     if (vmesa->newState & _NEW_DEPTH)
1463         viaChooseDepthState(ctx);
1464
1465     if (vmesa->newState & _NEW_FOG)
1466         viaChooseFogState(ctx);
1467
1468     if (vmesa->newState & _NEW_LINE)
1469         viaChooseLineState(ctx);
1470
1471     if (vmesa->newState & (_NEW_POLYGON | _NEW_POLYGONSTIPPLE)) {
1472         viaChoosePolygonState(ctx);
1473         viaChooseTriangle(ctx);
1474     }
1475
1476     if ((vmesa->newState & _NEW_STENCIL) && vmesa->have_hw_stencil)
1477         viaChooseStencilState(ctx);
1478     
1479     if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
1480         vmesa->regEnable |= HC_HenCS_MASK;
1481     else
1482         vmesa->regEnable &= ~HC_HenCS_MASK;
1483
1484     if (ctx->Point.SmoothFlag ||
1485         ctx->Line.SmoothFlag ||
1486         ctx->Polygon.SmoothFlag)
1487         vmesa->regEnable |= HC_HenAA_MASK;
1488     else 
1489         vmesa->regEnable &= ~HC_HenAA_MASK;
1490
1491     vmesa->newEmitState |= vmesa->newState;
1492     vmesa->newState = 0;
1493 }
1494
1495 static void viaInvalidateState(struct gl_context *ctx, GLuint newState)
1496 {
1497     struct via_context *vmesa = VIA_CONTEXT(ctx);
1498
1499     VIA_FINISH_PRIM( vmesa );
1500     vmesa->newState |= newState;
1501
1502     _swrast_InvalidateState(ctx, newState);
1503     _swsetup_InvalidateState(ctx, newState);
1504     _vbo_InvalidateState(ctx, newState);
1505     _tnl_InvalidateState(ctx, newState);
1506 }
1507
1508 void viaInitStateFuncs(struct gl_context *ctx)
1509 {
1510     /* Callbacks for internal Mesa events.
1511      */
1512     ctx->Driver.UpdateState = viaInvalidateState;
1513
1514     /* API callbacks
1515      */
1516     ctx->Driver.BlendEquationSeparate = viaBlendEquationSeparate;
1517     ctx->Driver.BlendFuncSeparate = viaBlendFuncSeparate;
1518     ctx->Driver.ClearColor = viaClearColor;
1519     ctx->Driver.ColorMask = viaColorMask;
1520     ctx->Driver.DrawBuffer = viaDrawBuffer;
1521     ctx->Driver.RenderMode = viaRenderMode;
1522     ctx->Driver.Scissor = viaScissor;
1523     ctx->Driver.DepthRange = viaDepthRange;
1524     ctx->Driver.Viewport = viaViewport;
1525     ctx->Driver.Enable = viaEnable;
1526
1527     /* XXX this should go away */
1528     ctx->Driver.ResizeBuffers = viaReAllocateBuffers;
1529 }