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