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