Fixed some suspicious pointer casts that caused lots of
[mesa.git] / src / mesa / drivers / dri / savage / savagestate.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
26 #include <stdio.h>
27
28 #include "mtypes.h"
29 #include "buffers.h"
30 #include "enums.h"
31 #include "macros.h"
32 #include "dd.h"
33
34 #include "mm.h"
35 #include "savagedd.h"
36 #include "savagecontext.h"
37
38 #include "savagestate.h"
39 #include "savagetex.h"
40 #include "savagetris.h"
41 #include "savageioctl.h"
42 #include "savage_bci.h"
43
44 #include "swrast/swrast.h"
45 #include "array_cache/acache.h"
46 #include "tnl/tnl.h"
47 #include "swrast_setup/swrast_setup.h"
48
49 #include "xmlpool.h"
50
51 static void savageBlendFunc_s4(GLcontext *);
52 static void savageBlendFunc_s3d(GLcontext *);
53
54 static __inline__ GLuint savagePackColor(GLuint format,
55 GLubyte r, GLubyte g,
56 GLubyte b, GLubyte a)
57 {
58 switch (format) {
59 case DV_PF_8888:
60 return SAVAGEPACKCOLOR8888(r,g,b,a);
61 case DV_PF_565:
62 return SAVAGEPACKCOLOR565(r,g,b);
63 default:
64
65 return 0;
66 }
67 }
68
69
70 static void savageDDAlphaFunc_s4(GLcontext *ctx, GLenum func, GLfloat ref)
71 {
72 savageBlendFunc_s4(ctx);
73 }
74 static void savageDDAlphaFunc_s3d(GLcontext *ctx, GLenum func, GLfloat ref)
75 {
76 savageBlendFunc_s3d(ctx);
77 }
78
79 static void savageDDBlendEquationSeparate(GLcontext *ctx,
80 GLenum modeRGB, GLenum modeA)
81 {
82 assert( modeRGB == modeA );
83
84 /* BlendEquation sets ColorLogicOpEnabled in an unexpected
85 * manner.
86 */
87 FALLBACK( ctx, SAVAGE_FALLBACK_LOGICOP,
88 (ctx->Color.ColorLogicOpEnabled &&
89 ctx->Color.LogicOp != GL_COPY));
90
91 /* Can only do blend addition, not min, max, subtract, etc. */
92 FALLBACK( ctx, SAVAGE_FALLBACK_BLEND_EQ,
93 modeRGB != GL_FUNC_ADD);
94 }
95
96
97 static void savageBlendFunc_s4(GLcontext *ctx)
98 {
99 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
100 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
101 u_int32_t drawCtrl0 = imesa->regs.s4.drawCtrl0.ui;
102 u_int32_t drawCtrl1 = imesa->regs.s4.drawCtrl1.ui;
103
104 /* set up draw control register (including blending, alpha
105 * test, and shading model)
106 */
107
108 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = 0;
109
110 /*
111 * blend modes
112 */
113 if(ctx->Color.BlendEnabled){
114 switch (ctx->Color.BlendDstRGB)
115 {
116 case GL_ZERO:
117 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
118 break;
119
120 case GL_ONE:
121 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
122 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
123 break;
124
125 case GL_SRC_COLOR:
126 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcClr;
127 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
128 break;
129
130 case GL_ONE_MINUS_SRC_COLOR:
131 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcClr;
132 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
133 break;
134
135 case GL_SRC_ALPHA:
136 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
137 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
138 break;
139
140 case GL_ONE_MINUS_SRC_ALPHA:
141 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
142 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
143 break;
144
145 case GL_DST_ALPHA:
146 if (imesa->glCtx->Visual.alphaBits == 0)
147 {
148 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_One;
149 }
150 else
151 {
152 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode= DAM_DstAlpha;
153 }
154 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
155 break;
156
157 case GL_ONE_MINUS_DST_ALPHA:
158 if (imesa->glCtx->Visual.alphaBits == 0)
159 {
160 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
161 }
162 else
163 {
164 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode=DAM_1DstAlpha;
165 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
166 }
167 break;
168 }
169
170 switch (ctx->Color.BlendSrcRGB)
171 {
172 case GL_ZERO:
173 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
174 break;
175
176 case GL_ONE:
177 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
178 break;
179
180 case GL_DST_COLOR:
181 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_DstClr;
182 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
183 break;
184
185 case GL_ONE_MINUS_DST_COLOR:
186 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1DstClr;
187 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites = GL_TRUE;
188 break;
189
190 case GL_SRC_ALPHA:
191 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
192 break;
193
194 case GL_ONE_MINUS_SRC_ALPHA:
195 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
196 break;
197
198 case GL_DST_ALPHA:
199 if (imesa->glCtx->Visual.alphaBits == 0)
200 {
201 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
202 }
203 else
204 {
205 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode= SAM_DstAlpha;
206 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
207 }
208 break;
209
210 case GL_ONE_MINUS_DST_ALPHA:
211 if (imesa->glCtx->Visual.alphaBits == 0)
212 {
213 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_Zero;
214 }
215 else
216 {
217 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode=SAM_1DstAlpha;
218 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
219 }
220 break;
221 }
222 }
223 else
224 {
225 imesa->regs.s4.drawLocalCtrl.ni.dstAlphaMode = DAM_Zero;
226 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
227 }
228
229 /* alpha test*/
230
231 if(ctx->Color.AlphaEnabled)
232 {
233 ACmpFunc a;
234 GLubyte alphaRef;
235
236 CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
237
238 switch(ctx->Color.AlphaFunc) {
239 case GL_NEVER: a = CF_Never; break;
240 case GL_ALWAYS: a = CF_Always; break;
241 case GL_LESS: a = CF_Less; break;
242 case GL_LEQUAL: a = CF_LessEqual; break;
243 case GL_EQUAL: a = CF_Equal; break;
244 case GL_GREATER: a = CF_Greater; break;
245 case GL_GEQUAL: a = CF_GreaterEqual; break;
246 case GL_NOTEQUAL: a = CF_NotEqual; break;
247 default:return;
248 }
249
250 imesa->regs.s4.drawCtrl1.ni.alphaTestEn = GL_TRUE;
251 imesa->regs.s4.drawCtrl1.ni.alphaTestCmpFunc = a;
252 imesa->regs.s4.drawCtrl0.ni.alphaRefVal = alphaRef;
253 }
254 else
255 {
256 imesa->regs.s4.drawCtrl1.ni.alphaTestEn = GL_FALSE;
257 }
258
259 /* Set/Reset Z-after-alpha*/
260
261 imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst =
262 imesa->regs.s4.drawCtrl1.ni.alphaTestEn;
263 /*imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn =
264 ~drawLocalCtrl.ni.wrZafterAlphaTst;*/
265
266 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
267 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
268 if (drawCtrl0 != imesa->regs.s4.drawCtrl0.ui ||
269 drawCtrl1 != imesa->regs.s4.drawCtrl1.ui)
270 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
271 }
272 static void savageBlendFunc_s3d(GLcontext *ctx)
273 {
274 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
275 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
276 u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
277
278 /* set up draw control register (including blending, alpha
279 * test, dithering, and shading model)
280 */
281
282 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = 0;
283
284 /*
285 * blend modes
286 */
287 if(ctx->Color.BlendEnabled){
288 switch (ctx->Color.BlendDstRGB)
289 {
290 case GL_ZERO:
291 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
292 break;
293
294 case GL_ONE:
295 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
296 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
297 break;
298
299 case GL_SRC_COLOR:
300 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcClr;
301 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
302 break;
303
304 case GL_ONE_MINUS_SRC_COLOR:
305 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcClr;
306 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
307 break;
308
309 case GL_SRC_ALPHA:
310 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_SrcAlpha;
311 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
312 break;
313
314 case GL_ONE_MINUS_SRC_ALPHA:
315 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1SrcAlpha;
316 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
317 break;
318
319 case GL_DST_ALPHA:
320 if (imesa->glCtx->Visual.alphaBits == 0)
321 {
322 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_One;
323 }
324 else
325 {
326 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_DstAlpha;
327 }
328 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
329 break;
330
331 case GL_ONE_MINUS_DST_ALPHA:
332 if (imesa->glCtx->Visual.alphaBits == 0)
333 {
334 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
335 }
336 else
337 {
338 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_1DstAlpha;
339 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
340 }
341 break;
342 }
343
344 switch (ctx->Color.BlendSrcRGB)
345 {
346 case GL_ZERO:
347 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
348 break;
349
350 case GL_ONE:
351 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
352 break;
353
354 case GL_DST_COLOR:
355 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstClr;
356 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
357 break;
358
359 case GL_ONE_MINUS_DST_COLOR:
360 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstClr;
361 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
362 break;
363
364 case GL_SRC_ALPHA:
365 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_SrcAlpha;
366 break;
367
368 case GL_ONE_MINUS_SRC_ALPHA:
369 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1SrcAlpha;
370 break;
371
372 case GL_DST_ALPHA:
373 if (imesa->glCtx->Visual.alphaBits == 0)
374 {
375 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
376 }
377 else
378 {
379 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_DstAlpha;
380 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
381 }
382 break;
383
384 case GL_ONE_MINUS_DST_ALPHA:
385 if (imesa->glCtx->Visual.alphaBits == 0)
386 {
387 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_Zero;
388 }
389 else
390 {
391 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_1DstAlpha;
392 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
393 }
394 break;
395 }
396 }
397 else
398 {
399 imesa->regs.s3d.drawCtrl.ni.dstAlphaMode = DAM_Zero;
400 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
401 }
402
403 /* alpha test*/
404
405 if(ctx->Color.AlphaEnabled)
406 {
407 ACmpFunc a;
408 GLubyte alphaRef;
409
410 CLAMPED_FLOAT_TO_UBYTE(alphaRef,ctx->Color.AlphaRef);
411
412 switch(ctx->Color.AlphaFunc) {
413 case GL_NEVER: a = CF_Never; break;
414 case GL_ALWAYS: a = CF_Always; break;
415 case GL_LESS: a = CF_Less; break;
416 case GL_LEQUAL: a = CF_LessEqual; break;
417 case GL_EQUAL: a = CF_Equal; break;
418 case GL_GREATER: a = CF_Greater; break;
419 case GL_GEQUAL: a = CF_GreaterEqual; break;
420 case GL_NOTEQUAL: a = CF_NotEqual; break;
421 default:return;
422 }
423
424 imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_TRUE;
425 imesa->regs.s3d.drawCtrl.ni.alphaTestCmpFunc = a;
426 imesa->regs.s3d.drawCtrl.ni.alphaRefVal = alphaRef;
427 }
428 else
429 {
430 imesa->regs.s3d.drawCtrl.ni.alphaTestEn = GL_FALSE;
431 }
432
433 /* Set/Reset Z-after-alpha*/
434
435 imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst =
436 imesa->regs.s3d.drawCtrl.ni.alphaTestEn;
437
438 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
439 zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
440 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
441 }
442
443 static void savageDDBlendFuncSeparate_s4( GLcontext *ctx, GLenum sfactorRGB,
444 GLenum dfactorRGB, GLenum sfactorA,
445 GLenum dfactorA )
446 {
447 assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
448 savageBlendFunc_s4( ctx );
449 }
450 static void savageDDBlendFuncSeparate_s3d( GLcontext *ctx, GLenum sfactorRGB,
451 GLenum dfactorRGB, GLenum sfactorA,
452 GLenum dfactorA )
453 {
454 assert (dfactorRGB == dfactorA && sfactorRGB == sfactorA);
455 savageBlendFunc_s3d( ctx );
456 }
457
458
459
460 static void savageDDDepthFunc_s4(GLcontext *ctx, GLenum func)
461 {
462 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
463 ZCmpFunc zmode;
464 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
465 u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
466 u_int32_t zWatermarks = imesa->regs.s4.zWatermarks.ui; /* FIXME: in DRM */
467
468 /* set up z-buffer control register (global)
469 * set up z-buffer offset register (global)
470 * set up z read/write watermarks register (global)
471 */
472
473 switch(func) { /* reversed (see savageCalcViewport) */
474 case GL_NEVER: zmode = CF_Never; break;
475 case GL_ALWAYS: zmode = CF_Always; break;
476 case GL_LESS: zmode = CF_Greater; break;
477 case GL_LEQUAL: zmode = CF_GreaterEqual; break;
478 case GL_EQUAL: zmode = CF_Equal; break;
479 case GL_GREATER: zmode = CF_Less; break;
480 case GL_GEQUAL: zmode = CF_LessEqual; break;
481 case GL_NOTEQUAL: zmode = CF_NotEqual; break;
482 default:return;
483 }
484 if (ctx->Depth.Test)
485 {
486
487 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = zmode;
488 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = ctx->Depth.Mask;
489 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
490 #if 1
491 imesa->regs.s4.zWatermarks.ni.wLow = 0;
492 #endif
493
494 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
495 }
496 else if (imesa->glCtx->Stencil.Enabled && imesa->hw_stencil)
497 {
498 /* Need to keep Z on for Stencil. */
499 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
500 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
501 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
502 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
503 imesa->regs.s4.zWatermarks.ni.wLow = 8;
504 }
505 else
506 {
507
508 if (imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn == GL_FALSE)
509 {
510 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
511 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
512 }
513 else
514
515 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
516 {
517 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_FALSE;
518 }
519 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
520 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
521 imesa->regs.s4.zWatermarks.ni.wLow = 8;
522 }
523
524 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
525 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
526 if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
527 zWatermarks != imesa->regs.s4.zWatermarks.ui)
528 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
529 }
530 static void savageDDDepthFunc_s3d(GLcontext *ctx, GLenum func)
531 {
532 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
533 ZCmpFunc zmode;
534 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
535 u_int32_t zBufCtrl = imesa->regs.s3d.zBufCtrl.ui;
536 u_int32_t zWatermarks = imesa->regs.s3d.zWatermarks.ui; /* FIXME: in DRM */
537
538 /* set up z-buffer control register (global)
539 * set up z-buffer offset register (global)
540 * set up z read/write watermarks register (global)
541 */
542 switch(func) { /* reversed (see savageCalcViewport) */
543 case GL_NEVER: zmode = CF_Never; break;
544 case GL_ALWAYS: zmode = CF_Always; break;
545 case GL_LESS: zmode = CF_Greater; break;
546 case GL_LEQUAL: zmode = CF_GreaterEqual; break;
547 case GL_EQUAL: zmode = CF_Equal; break;
548 case GL_GREATER: zmode = CF_Less; break;
549 case GL_GEQUAL: zmode = CF_LessEqual; break;
550 case GL_NOTEQUAL: zmode = CF_NotEqual; break;
551 default:return;
552 }
553 if (ctx->Depth.Test)
554 {
555 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
556 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = zmode;
557 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = ctx->Depth.Mask;
558
559 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
560 #if 1
561 imesa->regs.s3d.zWatermarks.ni.wLow = 0;
562 #endif
563 }
564 else
565 {
566 if (imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn == GL_FALSE) {
567 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Always;
568 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_TRUE;
569 }
570 else
571
572 /* DRAWUPDATE_REQUIRES_Z_ENABLED*/
573 {
574 imesa->regs.s3d.zBufCtrl.ni.zBufEn = GL_FALSE;
575 }
576 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_FALSE;
577 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
578 imesa->regs.s3d.zWatermarks.ni.wLow = 8;
579 }
580
581 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui ||
582 zBufCtrl != imesa->regs.s3d.zBufCtrl.ui)
583 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
584 if (zWatermarks != imesa->regs.s3d.zWatermarks.ui)
585 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
586 }
587
588 static void savageDDDepthMask_s4(GLcontext *ctx, GLboolean flag)
589 {
590 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
591 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
592
593 if (flag)
594 {
595 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_TRUE;
596 }
597 else
598 {
599 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites = GL_FALSE;
600 }
601 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
602
603 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
604 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
605 }
606 static void savageDDDepthMask_s3d(GLcontext *ctx, GLboolean flag)
607 {
608 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
609 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
610
611 if (flag)
612 {
613 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
614 }
615 else
616 {
617 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_FALSE;
618 }
619 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
620
621 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
622 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
623 }
624
625
626
627
628 /* =============================================================
629 * Hardware clipping
630 */
631
632
633 static void savageDDScissor( GLcontext *ctx, GLint x, GLint y,
634 GLsizei w, GLsizei h )
635 {
636 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
637
638 /* Emit buffered commands with old scissor state. */
639 FLUSH_BATCH(imesa);
640
641 /* Mirror scissors in private context. */
642 imesa->scissor.enabled = ctx->Scissor.Enabled;
643 imesa->scissor.x = x;
644 imesa->scissor.y = y;
645 imesa->scissor.w = w;
646 imesa->scissor.h = h;
647 }
648
649
650
651 static void savageDDDrawBuffer(GLcontext *ctx, GLenum mode )
652 {
653 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
654 u_int32_t destCtrl = imesa->regs.s4.destCtrl.ui;
655
656 /*
657 * _DrawDestMask is easier to cope with than <mode>.
658 */
659 switch ( ctx->Color._DrawDestMask[0] ) {
660 case DD_FRONT_LEFT_BIT:
661 imesa->IsDouble = GL_FALSE;
662 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->frontOffset>>11;
663
664 imesa->NotFirstFrame = GL_FALSE;
665 savageXMesaSetFrontClipRects( imesa );
666 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
667 break;
668 case DD_BACK_LEFT_BIT:
669 imesa->IsDouble = GL_TRUE;
670 imesa->regs.s4.destCtrl.ni.offset = imesa->savageScreen->backOffset>>11;
671 imesa->NotFirstFrame = GL_FALSE;
672 savageXMesaSetBackClipRects( imesa );
673 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_FALSE );
674 break;
675 default:
676 FALLBACK( ctx, SAVAGE_FALLBACK_DRAW_BUFFER, GL_TRUE );
677 return;
678 }
679
680 /* We want to update the s/w rast state too so that r200SetBuffer() (?)
681 * gets called.
682 */
683 _swrast_DrawBuffer(ctx, mode);
684
685 if (destCtrl != imesa->regs.s4.destCtrl.ui)
686 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
687 }
688
689 static void savageDDReadBuffer(GLcontext *ctx, GLenum mode )
690 {
691 /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */
692 }
693
694 #if 0
695 static void savageDDSetColor(GLcontext *ctx,
696 GLubyte r, GLubyte g,
697 GLubyte b, GLubyte a )
698 {
699 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
700 imesa->MonoColor = savagePackColor( imesa->savageScreen->frontFormat, r, g, b, a );
701 }
702 #endif
703
704 /* =============================================================
705 * Window position and viewport transformation
706 */
707
708 void savageCalcViewport( GLcontext *ctx )
709 {
710 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
711 const GLfloat *v = ctx->Viewport._WindowMap.m;
712 GLfloat *m = imesa->hw_viewport;
713
714 m[MAT_SX] = v[MAT_SX];
715 m[MAT_TX] = v[MAT_TX] + imesa->drawX + SUBPIXEL_X;
716 m[MAT_SY] = - v[MAT_SY];
717 m[MAT_TY] = - v[MAT_TY] + imesa->driDrawable->h + imesa->drawY + SUBPIXEL_Y;
718 /* Depth range is reversed (far: 0, near: 1) so that float depth
719 * compensates for loss of accuracy of far coordinates. */
720 if (imesa->float_depth && imesa->savageScreen->zpp == 2) {
721 /* The Savage 16-bit floating point depth format can't encode
722 * numbers < 2^-16. Make sure all depth values stay greater
723 * than that. */
724 m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale * (65535.0/65536.0);
725 m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale * (65535.0/65536.0);
726 } else {
727 m[MAT_SZ] = - v[MAT_SZ] * imesa->depth_scale;
728 m[MAT_TZ] = 1.0 - v[MAT_TZ] * imesa->depth_scale;
729 }
730
731 imesa->SetupNewInputs = ~0;
732 }
733
734 static void savageViewport( GLcontext *ctx,
735 GLint x, GLint y,
736 GLsizei width, GLsizei height )
737 {
738 /* update size of Mesa/software ancillary buffers */
739 _mesa_ResizeBuffersMESA();
740 savageCalcViewport( ctx );
741 }
742
743 static void savageDepthRange( GLcontext *ctx,
744 GLclampd nearval, GLclampd farval )
745 {
746 savageCalcViewport( ctx );
747 }
748
749
750 /* =============================================================
751 * Miscellaneous
752 */
753
754 static void savageDDClearColor(GLcontext *ctx,
755 const GLfloat color[4] )
756 {
757 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
758 GLubyte c[4];
759 CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
760 CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
761 CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
762 CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
763
764 imesa->ClearColor = savagePackColor( imesa->savageScreen->frontFormat,
765 c[0], c[1], c[2], c[3] );
766 }
767
768 /* Fallback to swrast for select and feedback.
769 */
770 static void savageRenderMode( GLcontext *ctx, GLenum mode )
771 {
772 FALLBACK( ctx, SAVAGE_FALLBACK_RENDERMODE, (mode != GL_RENDER) );
773 }
774
775
776 #if HW_CULL
777
778 /* =============================================================
779 * Culling - the savage isn't quite as clean here as the rest of
780 * its interfaces, but it's not bad.
781 */
782 static void savageDDCullFaceFrontFace(GLcontext *ctx, GLenum unused)
783 {
784 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
785 GLuint cullMode=imesa->LcsCullMode;
786 switch (ctx->Polygon.CullFaceMode)
787 {
788 case GL_FRONT:
789 switch (ctx->Polygon.FrontFace)
790 {
791 case GL_CW:
792 cullMode = BCM_CW;
793 break;
794 case GL_CCW:
795 cullMode = BCM_CCW;
796 break;
797 }
798 break;
799
800 case GL_BACK:
801 switch (ctx->Polygon.FrontFace)
802 {
803 case GL_CW:
804 cullMode = BCM_CCW;
805 break;
806 case GL_CCW:
807 cullMode = BCM_CW;
808 break;
809 }
810 break;
811 }
812 imesa->LcsCullMode = cullMode;
813 imesa->new_state |= SAVAGE_NEW_CULL;
814 }
815 #endif /* end #if HW_CULL */
816
817 static void savageUpdateCull( GLcontext *ctx )
818 {
819 #if HW_CULL
820 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
821 GLuint cullMode;
822 if (ctx->Polygon.CullFlag &&
823 imesa->raster_primitive >= GL_TRIANGLES &&
824 ctx->Polygon.CullFaceMode != GL_FRONT_AND_BACK)
825 cullMode = imesa->LcsCullMode;
826 else
827 cullMode = BCM_None;
828 if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
829 if (imesa->regs.s4.drawCtrl1.ni.cullMode != cullMode) {
830 imesa->regs.s4.drawCtrl1.ni.cullMode = cullMode;
831 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
832 }
833 } else {
834 if (imesa->regs.s3d.drawCtrl.ni.cullMode != cullMode) {
835 imesa->regs.s3d.drawCtrl.ni.cullMode = cullMode;
836 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
837 }
838 }
839 #endif /* end #if HW_CULL */
840 }
841
842
843
844 /* =============================================================
845 * Color masks
846 */
847
848 /* Mesa calls this from the wrong place - it is called a very large
849 * number of redundant times.
850 *
851 * Colormask can be simulated by multipass or multitexture techniques.
852 */
853 static void savageDDColorMask_s4(GLcontext *ctx,
854 GLboolean r, GLboolean g,
855 GLboolean b, GLboolean a )
856 {
857 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
858 GLuint enable;
859
860 if (ctx->Visual.alphaBits)
861 {
862 enable = b | g | r | a;
863 }
864 else
865 {
866 enable = b | g | r;
867 }
868
869 if (enable)
870 {
871 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
872 }
873 else
874 {
875 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_FALSE;
876 }
877 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
878 /* TODO: need a software fallback */
879 }
880 static void savageDDColorMask_s3d(GLcontext *ctx,
881 GLboolean r, GLboolean g,
882 GLboolean b, GLboolean a )
883 {
884 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
885 GLuint enable;
886
887 if (ctx->Visual.alphaBits)
888 {
889 enable = b | g | r | a;
890 }
891 else
892 {
893 enable = b | g | r;
894 }
895
896 if (enable)
897 {
898 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
899 }
900 else
901 {
902 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_FALSE;
903 }
904 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
905 /* TODO: need a software fallback */
906 }
907
908 /* Seperate specular not fully implemented in hardware... Needs
909 * some interaction with material state? Just punt to software
910 * in all cases?
911 * FK: Don't fall back for now. Let's see the failure cases and
912 * fix them the right way. I don't see how this could be a
913 * hardware limitation.
914 */
915 static void savageUpdateSpecular_s4(GLcontext *ctx) {
916 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
917 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
918
919 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
920 ctx->Light.Enabled) {
921 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_TRUE;
922 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
923 } else {
924 imesa->regs.s4.drawLocalCtrl.ni.specShadeEn = GL_FALSE;
925 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
926 }
927
928 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
929 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
930 }
931 static void savageUpdateSpecular_s3d(GLcontext *ctx) {
932 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
933 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
934
935 if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR &&
936 ctx->Light.Enabled) {
937 imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_TRUE;
938 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_TRUE);*/
939 } else {
940 imesa->regs.s3d.drawCtrl.ni.specShadeEn = GL_FALSE;
941 /*FALLBACK (ctx, SAVAGE_FALLBACK_SPECULAR, GL_FALSE);*/
942 }
943
944 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
945 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
946 }
947
948 static void savageDDLightModelfv_s4(GLcontext *ctx, GLenum pname,
949 const GLfloat *param)
950 {
951 savageUpdateSpecular_s4 (ctx);
952 }
953 static void savageDDLightModelfv_s3d(GLcontext *ctx, GLenum pname,
954 const GLfloat *param)
955 {
956 savageUpdateSpecular_s3d (ctx);
957 }
958
959 static void savageDDShadeModel_s4(GLcontext *ctx, GLuint mod)
960 {
961 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
962 u_int32_t drawLocalCtrl = imesa->regs.s4.drawLocalCtrl.ui;
963
964 if (mod == GL_SMOOTH)
965 {
966 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_FALSE;
967 }
968 else
969 {
970 imesa->regs.s4.drawLocalCtrl.ni.flatShadeEn = GL_TRUE;
971 }
972
973 if (drawLocalCtrl != imesa->regs.s4.drawLocalCtrl.ui)
974 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
975 }
976 static void savageDDShadeModel_s3d(GLcontext *ctx, GLuint mod)
977 {
978 savageContextPtr imesa = SAVAGE_CONTEXT( ctx );
979 u_int32_t drawCtrl = imesa->regs.s3d.drawCtrl.ui;
980
981 if (mod == GL_SMOOTH)
982 {
983 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_FALSE;
984 }
985 else
986 {
987 imesa->regs.s3d.drawCtrl.ni.flatShadeEn = GL_TRUE;
988 }
989
990 if (drawCtrl != imesa->regs.s3d.drawCtrl.ui)
991 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
992 }
993
994
995 /* =============================================================
996 * Fog
997 * The fogCtrl register has the same position and the same layout
998 * on savage3d and savage4. No need for two separate functions.
999 */
1000
1001 static void savageDDFogfv(GLcontext *ctx, GLenum pname, const GLfloat *param)
1002 {
1003 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1004 GLuint fogClr;
1005 u_int32_t fogCtrl = imesa->regs.s4.fogCtrl.ui;
1006
1007 /*if ((ctx->Fog.Enabled) &&(pname == GL_FOG_COLOR))*/
1008 if (ctx->Fog.Enabled)
1009 {
1010 fogClr = (((GLubyte)(ctx->Fog.Color[0]*255.0F) << 16) |
1011 ((GLubyte)(ctx->Fog.Color[1]*255.0F) << 8) |
1012 ((GLubyte)(ctx->Fog.Color[2]*255.0F) << 0));
1013 imesa->regs.s4.fogCtrl.ni.fogEn = GL_TRUE;
1014 /*cheap fog*/
1015 imesa->regs.s4.fogCtrl.ni.fogMode = GL_TRUE;
1016 imesa->regs.s4.fogCtrl.ni.fogClr = fogClr;
1017 }
1018 else
1019 {
1020 /*No fog*/
1021
1022 imesa->regs.s4.fogCtrl.ni.fogEn = 0;
1023 imesa->regs.s4.fogCtrl.ni.fogMode = 0;
1024 }
1025
1026 if (fogCtrl != imesa->regs.s4.fogCtrl.ui)
1027 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1028 }
1029
1030
1031 static void savageDDStencilFunc(GLcontext *ctx, GLenum func, GLint ref,
1032 GLuint mask)
1033 {
1034 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1035 SCmpFunc a=0;
1036 u_int32_t zBufCtrl = imesa->regs.s4.zBufCtrl.ui;
1037 u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
1038
1039 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = ctx->Stencil.Ref[0];
1040 imesa->regs.s4.stencilCtrl.ni.readMask = ctx->Stencil.ValueMask[0];
1041
1042 switch (ctx->Stencil.Function[0])
1043 {
1044 case GL_NEVER: a = CF_Never; break;
1045 case GL_ALWAYS: a = CF_Always; break;
1046 case GL_LESS: a = CF_Less; break;
1047 case GL_LEQUAL: a = CF_LessEqual; break;
1048 case GL_EQUAL: a = CF_Equal; break;
1049 case GL_GREATER: a = CF_Greater; break;
1050 case GL_GEQUAL: a = CF_GreaterEqual; break;
1051 case GL_NOTEQUAL: a = CF_NotEqual; break;
1052 default:
1053 break;
1054 }
1055
1056 imesa->regs.s4.stencilCtrl.ni.cmpFunc = a;
1057
1058 if (zBufCtrl != imesa->regs.s4.zBufCtrl.ui ||
1059 stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
1060 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1061 }
1062
1063 static void savageDDStencilMask(GLcontext *ctx, GLuint mask)
1064 {
1065 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1066
1067 if (imesa->regs.s4.stencilCtrl.ni.writeMask != ctx->Stencil.WriteMask[0]) {
1068 imesa->regs.s4.stencilCtrl.ni.writeMask = ctx->Stencil.WriteMask[0];
1069 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1070 }
1071 }
1072
1073 static void savageDDStencilOp(GLcontext *ctx, GLenum fail, GLenum zfail,
1074 GLenum zpass)
1075 {
1076 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1077 u_int32_t stencilCtrl = imesa->regs.s4.stencilCtrl.ui;
1078
1079 switch (ctx->Stencil.FailFunc[0])
1080 {
1081 case GL_KEEP:
1082 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1083 break;
1084 case GL_ZERO:
1085 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Zero;
1086 break;
1087 case GL_REPLACE:
1088 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Equal;
1089 break;
1090 case GL_INCR:
1091 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_IncClamp;
1092 break;
1093 case GL_DECR:
1094 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_DecClamp;
1095 break;
1096 case GL_INVERT:
1097 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Invert;
1098 break;
1099 case GL_INCR_WRAP_EXT:
1100 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Inc;
1101 break;
1102 case GL_DECR_WRAP_EXT:
1103 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Dec;
1104 break;
1105 }
1106
1107
1108 switch (ctx->Stencil.ZFailFunc[0])
1109 {
1110 case GL_KEEP:
1111 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1112 break;
1113 case GL_ZERO:
1114 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Zero;
1115 break;
1116 case GL_REPLACE:
1117 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Equal;
1118 break;
1119 case GL_INCR:
1120 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_IncClamp;
1121 break;
1122 case GL_DECR:
1123 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_DecClamp;
1124 break;
1125 case GL_INVERT:
1126 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Invert;
1127 break;
1128 case GL_INCR_WRAP_EXT:
1129 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Inc;
1130 break;
1131 case GL_DECR_WRAP_EXT:
1132 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Dec;
1133 break;
1134 }
1135
1136 switch (ctx->Stencil.ZPassFunc[0])
1137 {
1138 case GL_KEEP:
1139 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1140 break;
1141 case GL_ZERO:
1142 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Zero;
1143 break;
1144 case GL_REPLACE:
1145 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Equal;
1146 break;
1147 case GL_INCR:
1148 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_IncClamp;
1149 break;
1150 case GL_DECR:
1151 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_DecClamp;
1152 break;
1153 case GL_INVERT:
1154 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Invert;
1155 break;
1156 case GL_INCR_WRAP_EXT:
1157 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Inc;
1158 break;
1159 case GL_DECR_WRAP_EXT:
1160 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Dec;
1161 break;
1162 }
1163
1164 if (stencilCtrl != imesa->regs.s4.stencilCtrl.ui)
1165 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1166 }
1167
1168
1169 /* =============================================================
1170 */
1171
1172 static void savageDDEnable_s4(GLcontext *ctx, GLenum cap, GLboolean state)
1173 {
1174
1175 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1176 switch(cap) {
1177 case GL_ALPHA_TEST:
1178 /* we should consider the disable case*/
1179 savageBlendFunc_s4(ctx);
1180 break;
1181 case GL_BLEND:
1182 /*add the savageBlendFunc 2001/11/25
1183 * if call no such function, then glDisable(GL_BLEND) will do noting,
1184 *our chip has no disable bit
1185 */
1186 savageBlendFunc_s4(ctx);
1187 case GL_COLOR_LOGIC_OP:
1188 /* Fall through:
1189 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1190 */
1191 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1192 (ctx->Color.ColorLogicOpEnabled &&
1193 ctx->Color.LogicOp != GL_COPY));
1194 break;
1195 case GL_DEPTH_TEST:
1196 savageDDDepthFunc_s4(ctx,ctx->Depth.Func);
1197 break;
1198 case GL_SCISSOR_TEST:
1199 savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
1200 ctx->Scissor.Width, ctx->Scissor.Height);
1201 break;
1202 case GL_STENCIL_TEST:
1203 if (!imesa->hw_stencil)
1204 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1205 else {
1206 imesa->regs.s4.stencilCtrl.ni.stencilEn = state;
1207 if (ctx->Stencil.Enabled &&
1208 imesa->regs.s4.zBufCtrl.ni.zBufEn != GL_TRUE)
1209 {
1210 /* Stencil buffer requires Z enabled. */
1211 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Always;
1212 imesa->regs.s4.zBufCtrl.ni.zBufEn = GL_TRUE;
1213 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn = GL_FALSE;
1214 }
1215 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL | SAVAGE_UPLOAD_LOCAL;
1216 }
1217 break;
1218 case GL_FOG:
1219 savageDDFogfv(ctx,0,0);
1220 break;
1221 case GL_CULL_FACE:
1222 #if HW_CULL
1223 if (state)
1224 {
1225 savageDDCullFaceFrontFace(ctx,0);
1226 }
1227 else
1228 {
1229 imesa->LcsCullMode = BCM_None;
1230 imesa->new_state |= SAVAGE_NEW_CULL;
1231 }
1232 #endif
1233 break;
1234 case GL_DITHER:
1235 if (state)
1236 {
1237 if ( ctx->Color.DitherFlag )
1238 {
1239 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_TRUE;
1240 }
1241 }
1242 if (!ctx->Color.DitherFlag )
1243 {
1244 imesa->regs.s4.drawCtrl1.ni.ditherEn=GL_FALSE;
1245 }
1246 imesa->dirty |= SAVAGE_UPLOAD_GLOBAL;
1247 break;
1248
1249 case GL_LIGHTING:
1250 savageUpdateSpecular_s4 (ctx);
1251 break;
1252 case GL_TEXTURE_1D:
1253 case GL_TEXTURE_3D:
1254 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1255 break;
1256 case GL_TEXTURE_2D:
1257 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1258 break;
1259 default:
1260 ;
1261 }
1262 }
1263 static void savageDDEnable_s3d(GLcontext *ctx, GLenum cap, GLboolean state)
1264 {
1265
1266 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1267 switch(cap) {
1268 case GL_ALPHA_TEST:
1269 /* we should consider the disable case*/
1270 savageBlendFunc_s3d(ctx);
1271 break;
1272 case GL_BLEND:
1273 /*add the savageBlendFunc 2001/11/25
1274 * if call no such function, then glDisable(GL_BLEND) will do noting,
1275 *our chip has no disable bit
1276 */
1277 savageBlendFunc_s3d(ctx);
1278 case GL_COLOR_LOGIC_OP:
1279 /* Fall through:
1280 * For some reason enable(GL_BLEND) affects ColorLogicOpEnabled.
1281 */
1282 FALLBACK (ctx, SAVAGE_FALLBACK_LOGICOP,
1283 (ctx->Color.ColorLogicOpEnabled &&
1284 ctx->Color.LogicOp != GL_COPY));
1285 break;
1286 case GL_DEPTH_TEST:
1287 savageDDDepthFunc_s3d(ctx,ctx->Depth.Func);
1288 break;
1289 case GL_SCISSOR_TEST:
1290 savageDDScissor(ctx, ctx->Scissor.X, ctx->Scissor.Y,
1291 ctx->Scissor.Width, ctx->Scissor.Height);
1292 break;
1293 case GL_STENCIL_TEST:
1294 FALLBACK (ctx, SAVAGE_FALLBACK_STENCIL, state);
1295 break;
1296 case GL_FOG:
1297 savageDDFogfv(ctx,0,0);
1298 break;
1299 case GL_CULL_FACE:
1300 #if HW_CULL
1301 if (state)
1302 {
1303 savageDDCullFaceFrontFace(ctx,0);
1304 }
1305 else
1306 {
1307 imesa->LcsCullMode = BCM_None;
1308 imesa->new_state |= SAVAGE_NEW_CULL;
1309 }
1310 #endif
1311 break;
1312 case GL_DITHER:
1313 if (state)
1314 {
1315 if ( ctx->Color.DitherFlag )
1316 {
1317 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_TRUE;
1318 }
1319 }
1320 if (!ctx->Color.DitherFlag )
1321 {
1322 imesa->regs.s3d.drawCtrl.ni.ditherEn=GL_FALSE;
1323 }
1324 imesa->dirty |= SAVAGE_UPLOAD_LOCAL;
1325 break;
1326
1327 case GL_LIGHTING:
1328 savageUpdateSpecular_s3d (ctx);
1329 break;
1330 case GL_TEXTURE_1D:
1331 case GL_TEXTURE_3D:
1332 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1333 break;
1334 case GL_TEXTURE_2D:
1335 imesa->new_state |= SAVAGE_NEW_TEXTURE;
1336 break;
1337 default:
1338 ;
1339 }
1340 }
1341
1342 void savageDDUpdateHwState( GLcontext *ctx )
1343 {
1344 savageContextPtr imesa = SAVAGE_CONTEXT(ctx);
1345
1346 if (imesa->new_state) {
1347 savageFlushVertices(imesa);
1348 if (imesa->new_state & SAVAGE_NEW_TEXTURE) {
1349 savageUpdateTextureState( ctx );
1350 }
1351 if ((imesa->new_state & SAVAGE_NEW_CULL)) {
1352 savageUpdateCull(ctx);
1353 }
1354 imesa->new_state = 0;
1355 }
1356 }
1357
1358
1359 static void savageDDPrintDirty( const char *msg, GLuint state )
1360 {
1361 fprintf(stderr, "%s (0x%x): %s%s%s%s%s%s\n",
1362 msg,
1363 (unsigned int) state,
1364 (state & SAVAGE_UPLOAD_LOCAL) ? "upload-local, " : "",
1365 (state & SAVAGE_UPLOAD_TEX0) ? "upload-tex0, " : "",
1366 (state & SAVAGE_UPLOAD_TEX1) ? "upload-tex1, " : "",
1367 (state & SAVAGE_UPLOAD_FOGTBL) ? "upload-fogtbl, " : "",
1368 (state & SAVAGE_UPLOAD_GLOBAL) ? "upload-global, " : "",
1369 (state & SAVAGE_UPLOAD_TEXGLOBAL) ? "upload-texglobal, " : ""
1370 );
1371 }
1372
1373
1374 /**
1375 * Check if global registers were changed
1376 */
1377 static GLboolean savageGlobalRegChanged (savageContextPtr imesa,
1378 GLuint first, GLuint last) {
1379 GLuint i;
1380 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1381 if (((imesa->oldRegs.ui[i] ^ imesa->regs.ui[i]) &
1382 imesa->globalRegMask.ui[i]) != 0)
1383 return GL_TRUE;
1384 }
1385 return GL_FALSE;
1386 }
1387 static void savageEmitOldRegs (savageContextPtr imesa,
1388 GLuint first, GLuint last, GLboolean global) {
1389 GLuint n = last-first+1;
1390 drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
1391 cmd->state.cmd = SAVAGE_CMD_STATE;
1392 cmd->state.global = global;
1393 cmd->state.count = n;
1394 cmd->state.start = first;
1395 memcpy(cmd+1, &imesa->oldRegs.ui[first-SAVAGE_FIRST_REG], n*4);
1396 }
1397 static void savageEmitContiguousRegs (savageContextPtr imesa,
1398 GLuint first, GLuint last) {
1399 GLuint i;
1400 GLuint n = last-first+1;
1401 drm_savage_cmd_header_t *cmd = savageAllocCmdBuf(imesa, n*4);
1402 cmd->state.cmd = SAVAGE_CMD_STATE;
1403 cmd->state.global = savageGlobalRegChanged(imesa, first, last);
1404 cmd->state.count = n;
1405 cmd->state.start = first;
1406 memcpy(cmd+1, &imesa->regs.ui[first-SAVAGE_FIRST_REG], n*4);
1407 /* savageAllocCmdBuf may need to flush the cmd buffer and backup
1408 * the current hardware state. It should see the "old" (current)
1409 * state that has actually been emitted to the hardware. Therefore
1410 * this update is done *after* savageAllocCmdBuf. */
1411 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i)
1412 imesa->oldRegs.ui[i] = imesa->regs.ui[i];
1413 if (SAVAGE_DEBUG & DEBUG_STATE)
1414 fprintf (stderr, "Emitting regs 0x%02x-0x%02x\n", first, last);
1415 }
1416 static void savageEmitChangedRegs (savageContextPtr imesa,
1417 GLuint first, GLuint last) {
1418 GLuint i, firstChanged;
1419 firstChanged = SAVAGE_NR_REGS;
1420 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1421 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1422 if (firstChanged == SAVAGE_NR_REGS)
1423 firstChanged = i;
1424 } else {
1425 if (firstChanged != SAVAGE_NR_REGS) {
1426 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1427 i-1+SAVAGE_FIRST_REG);
1428 firstChanged = SAVAGE_NR_REGS;
1429 }
1430 }
1431 }
1432 if (firstChanged != SAVAGE_NR_REGS)
1433 savageEmitContiguousRegs (imesa, firstChanged+SAVAGE_FIRST_REG,
1434 last);
1435 }
1436 static void savageEmitChangedRegChunk (savageContextPtr imesa,
1437 GLuint first, GLuint last) {
1438 GLuint i;
1439 for (i = first - SAVAGE_FIRST_REG; i <= last - SAVAGE_FIRST_REG; ++i) {
1440 if (imesa->oldRegs.ui[i] != imesa->regs.ui[i]) {
1441 savageEmitContiguousRegs (imesa, first, last);
1442 break;
1443 }
1444 }
1445 }
1446 static void savageUpdateRegister_s4(savageContextPtr imesa)
1447 {
1448 /* In case the texture image was changed without changing the
1449 * texture address as well, we need to force emitting the texture
1450 * address in order to flush texture cashes. */
1451 if ((imesa->dirty & SAVAGE_UPLOAD_TEX0) &&
1452 imesa->oldRegs.s4.texAddr[0].ui == imesa->regs.s4.texAddr[0].ui)
1453 imesa->oldRegs.s4.texAddr[0].ui = 0xffffffff;
1454 if ((imesa->dirty & SAVAGE_UPLOAD_TEX1) &&
1455 imesa->oldRegs.s4.texAddr[1].ui == imesa->regs.s4.texAddr[1].ui)
1456 imesa->oldRegs.s4.texAddr[1].ui = 0xffffffff;
1457
1458 savageEmitChangedRegs (imesa, 0x1e, 0x39);
1459
1460 imesa->dirty=0;
1461 }
1462 static void savageUpdateRegister_s3d(savageContextPtr imesa)
1463 {
1464 /* Some temporary hacks to workaround lockups. Not sure if they are
1465 * still needed. But they work for now. */
1466 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1467 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1468
1469 /* the savage3d uses two contiguous ranges of BCI registers:
1470 * 0x18-0x1c and 0x20-0x38. Some texture registers need to be
1471 * emitted in one chunk or we get some funky rendering errors. */
1472 /* FIXME: watermark registers aren't programmed correctly ATM */
1473 savageEmitChangedRegs (imesa, 0x18, 0x19);
1474 savageEmitChangedRegChunk (imesa, 0x1a, 0x1c);
1475 savageEmitChangedRegs (imesa, 0x20, 0x36);
1476
1477 imesa->dirty=0;
1478 }
1479
1480
1481 void savageEmitOldState( savageContextPtr imesa )
1482 {
1483 assert(imesa->cmdBuf.write == imesa->cmdBuf.base);
1484 if (imesa->savageScreen->chipset >= S3_SAVAGE4) {
1485 savageEmitOldRegs (imesa, 0x1e, 0x39, GL_TRUE);
1486 } else {
1487 savageEmitOldRegs (imesa, 0x18, 0x1c, GL_TRUE);
1488 savageEmitOldRegs (imesa, 0x20, 0x36, GL_FALSE);
1489 }
1490 }
1491
1492
1493 /* Push the state into the sarea and/or texture memory.
1494 */
1495 void savageEmitChangedState( savageContextPtr imesa )
1496 {
1497 if (SAVAGE_DEBUG & DEBUG_VERBOSE_API)
1498 savageDDPrintDirty( "\n\n\nsavageEmitHwStateLocked", imesa->dirty );
1499
1500 if (imesa->dirty)
1501 {
1502 if (SAVAGE_DEBUG & DEBUG_VERBOSE_MSG)
1503 fprintf (stderr, "... emitting state\n");
1504 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1505 savageUpdateRegister_s4(imesa);
1506 else
1507 savageUpdateRegister_s3d(imesa);
1508 }
1509
1510 imesa->dirty = 0;
1511 }
1512
1513
1514 static void savageDDInitState_s4( savageContextPtr imesa )
1515 {
1516 #if 1
1517 imesa->regs.s4.destCtrl.ui = 1<<7;
1518 #endif
1519
1520 imesa->regs.s4.zBufCtrl.ni.zCmpFunc = CF_Less;
1521 imesa->regs.s4.zBufCtrl.ni.wToZEn = GL_TRUE;
1522 if (imesa->float_depth) {
1523 imesa->regs.s4.zBufCtrl.ni.zExpOffset =
1524 imesa->savageScreen->zpp == 2 ? 16 : 32;
1525 imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_TRUE;
1526 } else {
1527 imesa->regs.s4.zBufCtrl.ni.zExpOffset = 0;
1528 imesa->regs.s4.zBufCtrl.ni.floatZEn = GL_FALSE;
1529 }
1530 imesa->regs.s4.texBlendCtrl[0].ui = TBC_NoTexMap;
1531 imesa->regs.s4.texBlendCtrl[1].ui = TBC_NoTexMap1;
1532 imesa->regs.s4.drawCtrl0.ui = 0;
1533 #if 0
1534 imesa->regs.s4.drawCtrl1.ni.xyOffsetEn = 1;
1535 #endif
1536
1537 /* Set DestTexWatermarks_31,30 to 01 always.
1538 *Has no effect if dest. flush is disabled.
1539 */
1540 #if 0
1541 imesa->regs.s4.zWatermarks.ui = 0x12000C04;
1542 imesa->regs.s4.destTexWatermarks.ui = 0x40200400;
1543 #else
1544 imesa->regs.s4.zWatermarks.ui = 0x16001808;
1545 imesa->regs.s4.destTexWatermarks.ui = 0x4f000000;
1546 #endif
1547 imesa->regs.s4.drawCtrl0.ni.dPerfAccelEn = GL_TRUE;
1548
1549 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1550 * alpha blending working properly
1551 */
1552
1553 imesa->regs.s4.texCtrl[0].ni.dBias = 0x08;
1554 imesa->regs.s4.texCtrl[1].ni.dBias = 0x08;
1555 imesa->regs.s4.texCtrl[0].ni.texXprEn = GL_TRUE;
1556 imesa->regs.s4.texCtrl[1].ni.texXprEn = GL_TRUE;
1557 imesa->regs.s4.texCtrl[0].ni.dMax = 0x0f;
1558 imesa->regs.s4.texCtrl[1].ni.dMax = 0x0f;
1559 /* programm a valid tex address, in case texture state is emitted
1560 * in wrong order. */
1561 if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
1562 /* AGP textures available */
1563 imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[1]|3;
1564 imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[1]|3;
1565 } else {
1566 /* no AGP textures available, use local */
1567 imesa->regs.s4.texAddr[0].ui = imesa->savageScreen->textureOffset[0]|2;
1568 imesa->regs.s4.texAddr[1].ui = imesa->savageScreen->textureOffset[0]|2;
1569 }
1570 imesa->regs.s4.drawLocalCtrl.ni.drawUpdateEn = GL_TRUE;
1571 imesa->regs.s4.drawLocalCtrl.ni.srcAlphaMode = SAM_One;
1572 imesa->regs.s4.drawLocalCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1573 imesa->regs.s4.drawLocalCtrl.ni.flushPdZbufWrites= GL_TRUE;
1574 imesa->regs.s4.drawLocalCtrl.ni.flushPdDestWrites= GL_TRUE;
1575
1576 imesa->regs.s4.drawLocalCtrl.ni.zUpdateEn= GL_TRUE;
1577 imesa->regs.s4.drawCtrl1.ni.ditherEn = (
1578 driQueryOptioni(&imesa->optionCache, "color_reduction") ==
1579 DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
1580 imesa->regs.s4.drawCtrl1.ni.cullMode = BCM_None;
1581
1582 imesa->regs.s4.zBufCtrl.ni.stencilRefVal = 0x00;
1583
1584 imesa->regs.s4.stencilCtrl.ni.stencilEn = GL_FALSE;
1585 imesa->regs.s4.stencilCtrl.ni.cmpFunc = CF_Always;
1586 imesa->regs.s4.stencilCtrl.ni.failOp = STC_FAIL_Keep;
1587 imesa->regs.s4.stencilCtrl.ni.passZfailOp = STC_FAIL_Keep;
1588 imesa->regs.s4.stencilCtrl.ni.passZpassOp = STC_FAIL_Keep;
1589 imesa->regs.s4.stencilCtrl.ni.writeMask = 0xff;
1590 imesa->regs.s4.stencilCtrl.ni.readMask = 0xff;
1591
1592 imesa->LcsCullMode=BCM_None;
1593 imesa->regs.s4.texDescr.ni.palSize = TPS_256;
1594
1595 /* clear the local registers in the global reg mask */
1596 imesa->globalRegMask.s4.drawLocalCtrl.ui = 0;
1597 imesa->globalRegMask.s4.texPalAddr.ui = 0;
1598 imesa->globalRegMask.s4.texCtrl[0].ui = 0;
1599 imesa->globalRegMask.s4.texCtrl[1].ui = 0;
1600 imesa->globalRegMask.s4.texAddr[0].ui = 0;
1601 imesa->globalRegMask.s4.texAddr[1].ui = 0;
1602 imesa->globalRegMask.s4.texBlendCtrl[0].ui = 0;
1603 imesa->globalRegMask.s4.texBlendCtrl[1].ui = 0;
1604 imesa->globalRegMask.s4.texXprClr.ui = 0;
1605 imesa->globalRegMask.s4.texDescr.ui = 0;
1606 }
1607 static void savageDDInitState_s3d( savageContextPtr imesa )
1608 {
1609 #if 1
1610 imesa->regs.s3d.destCtrl.ui = 1<<7;
1611 #endif
1612
1613 imesa->regs.s3d.zBufCtrl.ni.zCmpFunc = CF_Less;
1614 #if 0
1615 imesa->regs.s3d.drawCtrl.ni.xyOffsetEn = 1;
1616 #endif
1617
1618 /* Set DestTexWatermarks_31,30 to 01 always.
1619 *Has no effect if dest. flush is disabled.
1620 */
1621 #if 0
1622 imesa->regs.s3d.zWatermarks.ui = 0x12000C04;
1623 imesa->regs.s3d.destTexWatermarks.ui = 0x40200400;
1624 #else
1625 imesa->regs.s3d.zWatermarks.ui = 0x16001808;
1626 imesa->regs.s3d.destTexWatermarks.ui = 0x4f000000;
1627 #endif
1628
1629 /* clrCmpAlphaBlendCtrl is needed to get alphatest and
1630 * alpha blending working properly
1631 */
1632
1633 imesa->regs.s3d.texCtrl.ni.dBias = 0x08;
1634 imesa->regs.s3d.texCtrl.ni.texXprEn = GL_TRUE;
1635 /* programm a valid tex address, in case texture state is emitted
1636 * in wrong order. */
1637 if (imesa->lastTexHeap == 2 && imesa->savageScreen->textureSize[1]) {
1638 /* AGP textures available */
1639 imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[1]|3;
1640 } else {
1641 /* no AGP textures available, use local */
1642 imesa->regs.s3d.texAddr.ui = imesa->savageScreen->textureOffset[0]|2;
1643 }
1644
1645 imesa->regs.s3d.zBufCtrl.ni.drawUpdateEn = GL_TRUE;
1646 imesa->regs.s3d.zBufCtrl.ni.wrZafterAlphaTst = GL_FALSE;
1647 imesa->regs.s3d.zBufCtrl.ni.zUpdateEn = GL_TRUE;
1648
1649 imesa->regs.s3d.drawCtrl.ni.srcAlphaMode = SAM_One;
1650 imesa->regs.s3d.drawCtrl.ni.flushPdZbufWrites = GL_TRUE;
1651 imesa->regs.s3d.drawCtrl.ni.flushPdDestWrites = GL_TRUE;
1652
1653 imesa->regs.s3d.drawCtrl.ni.ditherEn = (
1654 driQueryOptioni(&imesa->optionCache, "color_reduction") ==
1655 DRI_CONF_COLOR_REDUCTION_DITHER) ? GL_TRUE : GL_FALSE;
1656 imesa->regs.s3d.drawCtrl.ni.cullMode = BCM_None;
1657
1658 imesa->LcsCullMode = BCM_None;
1659 imesa->regs.s3d.texDescr.ni.palSize = TPS_256;
1660
1661 /* clear the local registers in the global reg mask */
1662 imesa->globalRegMask.s3d.texPalAddr.ui = 0;
1663 imesa->globalRegMask.s3d.texXprClr.ui = 0;
1664 imesa->globalRegMask.s3d.texAddr.ui = 0;
1665 imesa->globalRegMask.s3d.texDescr.ui = 0;
1666 imesa->globalRegMask.s3d.texCtrl.ui = 0;
1667
1668 imesa->globalRegMask.s3d.fogCtrl.ui = 0;
1669
1670 /* drawCtrl is local with some exceptions */
1671 imesa->globalRegMask.s3d.drawCtrl.ui = 0;
1672 imesa->globalRegMask.s3d.drawCtrl.ni.cullMode = 0x3;
1673 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestCmpFunc = 0x7;
1674 imesa->globalRegMask.s3d.drawCtrl.ni.alphaTestEn = 0x1;
1675 imesa->globalRegMask.s3d.drawCtrl.ni.alphaRefVal = 0xff;
1676
1677 /* zBufCtrl is local with some exceptions */
1678 imesa->globalRegMask.s3d.zBufCtrl.ui = 0;
1679 imesa->globalRegMask.s3d.zBufCtrl.ni.zCmpFunc = 0x7;
1680 imesa->globalRegMask.s3d.zBufCtrl.ni.zBufEn = 0x1;
1681 }
1682 void savageDDInitState( savageContextPtr imesa ) {
1683 memset (imesa->regs.ui, 0, SAVAGE_NR_REGS*sizeof(u_int32_t));
1684 memset (imesa->globalRegMask.ui, 0xff, SAVAGE_NR_REGS*sizeof(u_int32_t));
1685 if (imesa->savageScreen->chipset >= S3_SAVAGE4)
1686 savageDDInitState_s4 (imesa);
1687 else
1688 savageDDInitState_s3d (imesa);
1689
1690 /*fprintf(stderr,"DBflag:%d\n",imesa->glCtx->Visual->DBflag);*/
1691 /* zbufoffset and destctrl have the same position and layout on
1692 * savage4 and savage3d. */
1693 if (imesa->glCtx->Visual.doubleBufferMode) {
1694 imesa->IsDouble = GL_TRUE;
1695 imesa->toggle = TARGET_BACK;
1696 imesa->regs.s4.destCtrl.ni.offset =
1697 imesa->savageScreen->backOffset>>11;
1698 } else {
1699 imesa->IsDouble = GL_FALSE;
1700 imesa->toggle = TARGET_FRONT;
1701 imesa->regs.s4.destCtrl.ni.offset =
1702 imesa->savageScreen->frontOffset>>11;
1703 }
1704 if(imesa->savageScreen->cpp == 2) {
1705 imesa->regs.s4.destCtrl.ni.dstPixFmt = 0;
1706 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1707 (imesa->savageScreen->width+63)>>6;
1708 } else {
1709 imesa->regs.s4.destCtrl.ni.dstPixFmt = 1;
1710 imesa->regs.s4.destCtrl.ni.dstWidthInTile =
1711 (imesa->savageScreen->width+31)>>5;
1712 }
1713 imesa->drawMap = imesa->apertureBase[imesa->toggle];
1714 imesa->readMap = imesa->apertureBase[imesa->toggle];
1715 imesa->NotFirstFrame = GL_FALSE;
1716
1717 imesa->regs.s4.zBufOffset.ni.offset=imesa->savageScreen->depthOffset>>11;
1718 if(imesa->savageScreen->zpp == 2) {
1719 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1720 (imesa->savageScreen->width+63)>>6;
1721 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 0;
1722 } else {
1723 imesa->regs.s4.zBufOffset.ni.zBufWidthInTiles =
1724 (imesa->savageScreen->width+31)>>5;
1725 imesa->regs.s4.zBufOffset.ni.zDepthSelect = 1;
1726 }
1727
1728 memcpy (imesa->oldRegs.ui, imesa->regs.ui, SAVAGE_NR_REGS*sizeof(u_int32_t));
1729
1730 /* Emit the initial state to the (empty) command buffer. */
1731 assert (imesa->cmdBuf.write == imesa->cmdBuf.base);
1732 savageEmitOldState(imesa);
1733 imesa->cmdBuf.start = imesa->cmdBuf.write;
1734 }
1735
1736
1737 #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|\
1738 NEW_TEXTURE_MATRIX|\
1739 NEW_USER_CLIP|NEW_CLIENT_STATE))
1740
1741 static void savageDDInvalidateState( GLcontext *ctx, GLuint new_state )
1742 {
1743 _swrast_InvalidateState( ctx, new_state );
1744 _swsetup_InvalidateState( ctx, new_state );
1745 _ac_InvalidateState( ctx, new_state );
1746 _tnl_InvalidateState( ctx, new_state );
1747 SAVAGE_CONTEXT(ctx)->new_gl_state |= new_state;
1748 }
1749
1750
1751 void savageDDInitStateFuncs(GLcontext *ctx)
1752 {
1753 ctx->Driver.UpdateState = savageDDInvalidateState;
1754 ctx->Driver.BlendEquationSeparate = savageDDBlendEquationSeparate;
1755 ctx->Driver.Fogfv = savageDDFogfv;
1756 ctx->Driver.Scissor = savageDDScissor;
1757 #if HW_CULL
1758 ctx->Driver.CullFace = savageDDCullFaceFrontFace;
1759 ctx->Driver.FrontFace = savageDDCullFaceFrontFace;
1760 #else
1761 ctx->Driver.CullFace = 0;
1762 ctx->Driver.FrontFace = 0;
1763 #endif /* end #if HW_CULL */
1764 ctx->Driver.PolygonMode=NULL;
1765 ctx->Driver.PolygonStipple = 0;
1766 ctx->Driver.LineStipple = 0;
1767 ctx->Driver.LineWidth = 0;
1768 ctx->Driver.LogicOpcode = 0;
1769 ctx->Driver.DrawBuffer = savageDDDrawBuffer;
1770 ctx->Driver.ReadBuffer = savageDDReadBuffer;
1771 ctx->Driver.ClearColor = savageDDClearColor;
1772
1773 ctx->Driver.DepthRange = savageDepthRange;
1774 ctx->Driver.Viewport = savageViewport;
1775 ctx->Driver.RenderMode = savageRenderMode;
1776
1777 ctx->Driver.ClearIndex = 0;
1778 ctx->Driver.IndexMask = 0;
1779
1780 if (SAVAGE_CONTEXT( ctx )->savageScreen->chipset >= S3_SAVAGE4) {
1781 ctx->Driver.Enable = savageDDEnable_s4;
1782 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s4;
1783 ctx->Driver.DepthFunc = savageDDDepthFunc_s4;
1784 ctx->Driver.DepthMask = savageDDDepthMask_s4;
1785 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s4;
1786 ctx->Driver.ColorMask = savageDDColorMask_s4;
1787 ctx->Driver.ShadeModel = savageDDShadeModel_s4;
1788 ctx->Driver.LightModelfv = savageDDLightModelfv_s4;
1789 ctx->Driver.StencilFunc = savageDDStencilFunc;
1790 ctx->Driver.StencilMask = savageDDStencilMask;
1791 ctx->Driver.StencilOp = savageDDStencilOp;
1792 } else {
1793 ctx->Driver.Enable = savageDDEnable_s3d;
1794 ctx->Driver.AlphaFunc = savageDDAlphaFunc_s3d;
1795 ctx->Driver.DepthFunc = savageDDDepthFunc_s3d;
1796 ctx->Driver.DepthMask = savageDDDepthMask_s3d;
1797 ctx->Driver.BlendFuncSeparate = savageDDBlendFuncSeparate_s3d;
1798 ctx->Driver.ColorMask = savageDDColorMask_s3d;
1799 ctx->Driver.ShadeModel = savageDDShadeModel_s3d;
1800 ctx->Driver.LightModelfv = savageDDLightModelfv_s3d;
1801 ctx->Driver.StencilFunc = 0;
1802 ctx->Driver.StencilMask = 0;
1803 ctx->Driver.StencilOp = 0;
1804 }
1805
1806 /* Swrast hooks for imaging extensions:
1807 */
1808 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1809 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1810 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1811 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1812 }