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