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