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