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