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